diff --git a/include/__tuple b/include/__tuple index 1213262d..9a6b6e09 100644 --- a/include/__tuple +++ b/include/__tuple @@ -79,47 +79,47 @@ template struct __tuple_like > : true_type template struct __tuple_like > : true_type {}; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type& get(tuple<_Tp...>&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, tuple<_Tp...> >::type& get(const tuple<_Tp...>&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(tuple<_Tp...>&&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(const pair<_T1, _T2>&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(pair<_T1, _T2>&&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp& get(array<_Tp, _Size>&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Tp& get(const array<_Tp, _Size>&) _NOEXCEPT; template -_LIBCPP_INLINE_VISIBILITY +_LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& get(array<_Tp, _Size>&&) _NOEXCEPT; diff --git a/include/array b/include/array index bcf53478..86d1fc0b 100644 --- a/include/array +++ b/include/array @@ -59,14 +59,14 @@ struct array // element access: reference operator[](size_type n); - const_reference operator[](size_type n) const; - const_reference at(size_type n) const; + 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; + const_reference front() const; // constexpr in C++14 reference back(); - const_reference back() const; + const_reference back() const; // constexpr in C++14 T* data() noexcept; const T* data() const noexcept; @@ -92,9 +92,9 @@ template class tuple_size; template class tuple_element; template struct tuple_size>; template struct tuple_element>; -template T& get(array&) noexcept; -template const T& get(const array&) noexcept; -template T&& get(array&&) noexcept; +template T& get(array&) noexcept; // constexpr in C++14 +template const T& get(const array&) noexcept; // constexpr in C++14 +template T&& get(array&&) noexcept; // constexpr in C++14 } // std @@ -181,14 +181,14 @@ struct _LIBCPP_TYPE_VIS array // element access: _LIBCPP_INLINE_VISIBILITY reference operator[](size_type __n) {return __elems_[__n];} - _LIBCPP_INLINE_VISIBILITY const_reference operator[](size_type __n) const {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); - const_reference at(size_type __n) const; + _LIBCPP_CONSTEXPR_AFTER_CXX11 const_reference at(size_type __n) const; _LIBCPP_INLINE_VISIBILITY reference front() {return __elems_[0];} - _LIBCPP_INLINE_VISIBILITY const_reference front() const {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 const_reference back() const {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 value_type* data() _NOEXCEPT {return __elems_;} @@ -210,6 +210,7 @@ array<_Tp, _Size>::at(size_type __n) } template +_LIBCPP_CONSTEXPR_AFTER_CXX11 typename array<_Tp, _Size>::const_reference array<_Tp, _Size>::at(size_type __n) const { @@ -306,32 +307,32 @@ public: }; template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp& get(array<_Tp, _Size>& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array)"); - return __a[_Ip]; + return __a.__elems_[_Ip]; } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const _Tp& get(const array<_Tp, _Size>& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (const std::array)"); - return __a[_Ip]; + return __a.__elems_[_Ip]; } #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR_AFTER_CXX11 _Tp&& get(array<_Tp, _Size>&& __a) _NOEXCEPT { static_assert(_Ip < _Size, "Index out of bounds in std::get<> (std::array &&)"); - return _VSTD::move(__a[_Ip]); + return _VSTD::move(__a.__elems_[_Ip]); } #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES diff --git a/include/tuple b/include/tuple index c7a1c143..5d5debfa 100644 --- a/include/tuple +++ b/include/tuple @@ -86,13 +86,13 @@ template class tuple_element>; // 20.4.1.5, element access: template typename tuple_element>::type& - get(tuple&) noexcept; + get(tuple&) noexcept; // constexpr in C++14 template typename tuple_element>::type const& - get(const tuple&) noexcept; + get(const tuple&) noexcept; // constexpr in C++14 template typename tuple_element>::type&& - get(tuple&&) noexcept; + get(tuple&&) noexcept; // constexpr in C++14 template constexpr T1& get(tuple&) noexcept; // C++14 @@ -546,11 +546,11 @@ class _LIBCPP_TYPE_VIS tuple base base_; - template friend + template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type& get(tuple<_Up...>&) _NOEXCEPT; - template friend + template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Jp, tuple<_Up...> >::type& get(const tuple<_Up...>&) _NOEXCEPT; - template friend + template friend _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Jp, tuple<_Up...> >::type&& get(tuple<_Up...>&&) _NOEXCEPT; public: @@ -763,7 +763,7 @@ swap(tuple<_Tp...>& __t, tuple<_Tp...>& __u) // get template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type& get(tuple<_Tp...>& __t) _NOEXCEPT { @@ -772,7 +772,7 @@ get(tuple<_Tp...>& __t) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, tuple<_Tp...> >::type& get(const tuple<_Tp...>& __t) _NOEXCEPT { @@ -781,7 +781,7 @@ get(const tuple<_Tp...>& __t) _NOEXCEPT } template -inline _LIBCPP_INLINE_VISIBILITY +inline _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, tuple<_Tp...> >::type&& get(tuple<_Tp...>&& __t) _NOEXCEPT { diff --git a/include/utility b/include/utility index 2d2670d6..d36cf9dd 100644 --- a/include/utility +++ b/include/utility @@ -107,15 +107,15 @@ template struct tuple_element<1, std::pair >; template typename tuple_element >::type& - get(std::pair&) noexcept; + get(std::pair&) noexcept; // constexpr in C++14 template const typename const tuple_element >::type& - get(const std::pair&) noexcept; + get(const std::pair&) noexcept; // constexpr in C++14 template typename tuple_element >::type&& - get(std::pair&&) noexcept; + get(std::pair&&) noexcept; // constexpr in C++14 template constexpr T1& get(std::pair&) noexcept; // C++14 @@ -546,13 +546,13 @@ struct __get_pair<0> { template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _T1& get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _T1& get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.first;} @@ -560,7 +560,7 @@ struct __get_pair<0> template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _T1&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T1>(__p.first);} @@ -572,13 +572,13 @@ struct __get_pair<1> { template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _T2& get(pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 const _T2& get(const pair<_T1, _T2>& __p) _NOEXCEPT {return __p.second;} @@ -586,7 +586,7 @@ struct __get_pair<1> template static - _LIBCPP_INLINE_VISIBILITY + _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR_AFTER_CXX11 _T2&& get(pair<_T1, _T2>&& __p) _NOEXCEPT {return _VSTD::forward<_T2>(__p.second);} @@ -594,7 +594,7 @@ struct __get_pair<1> }; template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>& __p) _NOEXCEPT { @@ -602,7 +602,7 @@ get(pair<_T1, _T2>& __p) _NOEXCEPT } template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR_AFTER_CXX11 const typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(const pair<_T1, _T2>& __p) _NOEXCEPT { @@ -612,7 +612,7 @@ get(const pair<_T1, _T2>& __p) _NOEXCEPT #ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES template -_LIBCPP_INLINE_VISIBILITY inline +_LIBCPP_INLINE_VISIBILITY inline _LIBCPP_CONSTEXPR_AFTER_CXX11 typename tuple_element<_Ip, pair<_T1, _T2> >::type&& get(pair<_T1, _T2>&& __p) _NOEXCEPT { diff --git a/test/containers/sequences/array/array.size/size.pass.cpp b/test/containers/sequences/array/array.size/size.pass.cpp index 4078fd5c..fe5a0d5c 100644 --- a/test/containers/sequences/array/array.size/size.pass.cpp +++ b/test/containers/sequences/array/array.size/size.pass.cpp @@ -21,12 +21,16 @@ int main() typedef std::array C; C c = {1, 2, 3.5}; assert(c.size() == 3); + assert(c.max_size() == 3); + assert(!c.empty()); } { typedef double T; typedef std::array C; C c = {}; assert(c.size() == 0); + assert(c.max_size() == 0); + assert(c.empty()); } #ifndef _LIBCPP_HAS_NO_CONSTEXPR { @@ -34,12 +38,16 @@ int main() typedef std::array C; constexpr C c = {1, 2, 3.5}; static_assert(c.size() == 3, ""); + static_assert(c.max_size() == 3, ""); + static_assert(!c.empty(), ""); } { typedef double T; typedef std::array C; constexpr C c = {}; static_assert(c.size() == 0, ""); + static_assert(c.max_size() == 0, ""); + static_assert(c.empty(), ""); } #endif } diff --git a/test/containers/sequences/array/array.tuple/get.pass.cpp b/test/containers/sequences/array/array.tuple/get.pass.cpp index 9820babc..d9e242cd 100644 --- a/test/containers/sequences/array/array.tuple/get.pass.cpp +++ b/test/containers/sequences/array/array.tuple/get.pass.cpp @@ -14,6 +14,16 @@ #include #include +#if __cplusplus > 201103L +struct S { + std::array a; + int k; + constexpr S() : a{1,2,3}, k(std::get<2>(a)) {} + }; + +constexpr std::array getArr () { return { 3, 4 }; } +#endif + int main() { { @@ -25,4 +35,18 @@ int main() assert(c[1] == 5.5); assert(c[2] == 3.5); } +#if _LIBCPP_STD_VER > 11 + { + typedef double T; + typedef std::array C; + constexpr C c = {1, 2, 3.5}; + static_assert(std::get<0>(c) == 1, ""); + static_assert(std::get<1>(c) == 2, ""); + static_assert(std::get<2>(c) == 3.5, ""); + } + { + static_assert(S().k == 3, ""); + static_assert(std::get<1>(getArr()) == 4, ""); + } +#endif } diff --git a/test/containers/sequences/array/array.tuple/get_const.pass.cpp b/test/containers/sequences/array/array.tuple/get_const.pass.cpp index 6ede8f0c..1cbdfa4f 100644 --- a/test/containers/sequences/array/array.tuple/get_const.pass.cpp +++ b/test/containers/sequences/array/array.tuple/get_const.pass.cpp @@ -24,4 +24,14 @@ int main() assert(std::get<1>(c) == 2); assert(std::get<2>(c) == 3.5); } +#if _LIBCPP_STD_VER > 11 + { + typedef double T; + typedef std::array C; + constexpr const C c = {1, 2, 3.5}; + static_assert(std::get<0>(c) == 1, ""); + static_assert(std::get<1>(c) == 2, ""); + static_assert(std::get<2>(c) == 3.5, ""); + } +#endif } diff --git a/test/containers/sequences/array/at.pass.cpp b/test/containers/sequences/array/at.pass.cpp new file mode 100644 index 00000000..b5cf8a5a --- /dev/null +++ b/test/containers/sequences/array/at.pass.cpp @@ -0,0 +1,67 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// reference operator[] (size_type) +// const_reference operator[] (size_type); // constexpr in C++14 +// reference at (size_type) +// const_reference at (size_type); // constexpr in C++14 + +#include +#include + +int main() +{ + { + typedef double T; + typedef std::array C; + C c = {1, 2, 3.5}; + C::reference r1 = c.at(0); + assert(r1 == 1); + r1 = 5.5; + assert(c.front() == 5.5); + + C::reference r2 = c.at(2); + assert(r2 == 3.5); + r2 = 7.5; + assert(c.back() == 7.5); + + try { (void) c.at(3); } + catch (const std::out_of_range &) {} + } + { + typedef double T; + typedef std::array C; + const C c = {1, 2, 3.5}; + C::const_reference r1 = c.at(0); + assert(r1 == 1); + + C::const_reference r2 = c.at(2); + assert(r2 == 3.5); + + try { (void) c.at(3); } + catch (const std::out_of_range &) {} + } + +#if _LIBCPP_STD_VER > 11 + { + typedef double T; + typedef std::array C; + constexpr C c = {1, 2, 3.5}; + + constexpr T t1 = c.at(0); + static_assert (t1 == 1, ""); + + constexpr T t2 = c.at(2); + static_assert (t2 == 3.5, ""); + } +#endif + +} diff --git a/test/containers/sequences/array/front_back.pass.cpp b/test/containers/sequences/array/front_back.pass.cpp new file mode 100644 index 00000000..45a963b9 --- /dev/null +++ b/test/containers/sequences/array/front_back.pass.cpp @@ -0,0 +1,62 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// reference front(); +// reference back(); +// const_reference front(); // constexpr in C++14 +// const_reference back(); // constexpr in C++14 + +#include +#include + +int main() +{ + { + typedef double T; + typedef std::array C; + C c = {1, 2, 3.5}; + + C::reference r1 = c.front(); + assert(r1 == 1); + r1 = 5.5; + assert(c[0] == 5.5); + + C::reference r2 = c.back(); + assert(r2 == 3.5); + r2 = 7.5; + assert(c[2] == 7.5); + } + { + typedef double T; + typedef std::array C; + const C c = {1, 2, 3.5}; + C::const_reference r1 = c.front(); + assert(r1 == 1); + + C::const_reference r2 = c.back(); + assert(r2 == 3.5); + } + +#if _LIBCPP_STD_VER > 11 + { + typedef double T; + typedef std::array C; + constexpr C c = {1, 2, 3.5}; + + constexpr T t1 = c.front(); + static_assert (t1 == 1, ""); + + constexpr T t2 = c.back(); + static_assert (t2 == 3.5, ""); + } +#endif + +} diff --git a/test/containers/sequences/array/indexing.pass.cpp b/test/containers/sequences/array/indexing.pass.cpp new file mode 100644 index 00000000..e4dda0dc --- /dev/null +++ b/test/containers/sequences/array/indexing.pass.cpp @@ -0,0 +1,60 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// reference operator[] (size_type) +// const_reference operator[] (size_type); // constexpr in C++14 +// reference at (size_type) +// const_reference at (size_type); // constexpr in C++14 + +#include +#include + +int main() +{ + { + typedef double T; + typedef std::array C; + C c = {1, 2, 3.5}; + C::reference r1 = c[0]; + assert(r1 == 1); + r1 = 5.5; + assert(c.front() == 5.5); + + C::reference r2 = c[2]; + assert(r2 == 3.5); + r2 = 7.5; + assert(c.back() == 7.5); + } + { + typedef double T; + typedef std::array C; + const C c = {1, 2, 3.5}; + C::const_reference r1 = c[0]; + assert(r1 == 1); + C::const_reference r2 = c[2]; + assert(r2 == 3.5); + } + +#if _LIBCPP_STD_VER > 11 + { + typedef double T; + typedef std::array C; + constexpr C c = {1, 2, 3.5}; + + constexpr T t1 = c[0]; + static_assert (t1 == 1, ""); + + constexpr T t2 = c[2]; + static_assert (t2 == 3.5, ""); + } +#endif + +} diff --git a/test/utilities/utility/pairs/pair.astuple/get_const.pass.cpp b/test/utilities/utility/pairs/pair.astuple/get_const.pass.cpp index 43e70ea5..fcda3664 100644 --- a/test/utilities/utility/pairs/pair.astuple/get_const.pass.cpp +++ b/test/utilities/utility/pairs/pair.astuple/get_const.pass.cpp @@ -31,10 +31,8 @@ int main() { typedef std::pair P; constexpr P p1(3, 4); - static_assert(p1.first == 3, "" ); // for now! - static_assert(p1.second == 4, "" ); // for now! -// static_assert(std::get<0>(p1) == 3, ""); -// static_assert(std::get<1>(p1) == 4, ""); + static_assert(std::get<0>(p1) == 3, ""); + static_assert(std::get<1>(p1) == 4, ""); } #endif } diff --git a/test/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp b/test/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp index ebfbe9e4..6d61c47f 100644 --- a/test/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp +++ b/test/utilities/utility/pairs/pair.astuple/get_non_const.pass.cpp @@ -18,6 +18,16 @@ #include #include +#if __cplusplus > 201103L +struct S { + std::pair a; + int k; + constexpr S() : a{1,2}, k(std::get<0>(a)) {} + }; + +constexpr std::pair getP () { return { 3, 4 }; } +#endif + int main() { { @@ -30,4 +40,12 @@ int main() assert(std::get<0>(p) == 5); assert(std::get<1>(p) == 6); } + +#if __cplusplus > 201103L + { + static_assert(S().k == 1, ""); + static_assert(std::get<1>(getP()) == 4, ""); + } +#endif + }