diff --git a/include/__tuple b/include/__tuple index a2d4e02f3..22134a205 100644 --- a/include/__tuple +++ b/include/__tuple @@ -83,6 +83,10 @@ template const typename tuple_element<_Ip, tuple<_Tp...>>::type& get(const tuple<_Tp...>&); +template +typename tuple_element<_Ip, tuple<_Tp...>>::type&& +get(tuple<_Tp...>&&); + template typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(pair<_T1, _T2>&); @@ -91,6 +95,10 @@ template const typename tuple_element<_Ip, pair<_T1, _T2> >::type& get(const pair<_T1, _T2>&); +template +typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(pair<_T1, _T2>&&); + template _Tp& get(array<_Tp, _Size>&); @@ -99,6 +107,10 @@ template const _Tp& get(const array<_Tp, _Size>&); +template +_Tp&& +get(array<_Tp, _Size>&&); + // __make_tuple_indices template struct __tuple_indices {}; diff --git a/include/array b/include/array index 2c3d89cde..380126229 100644 --- a/include/array +++ b/include/array @@ -94,6 +94,7 @@ template struct tuple_size>; template struct tuple_element>; template T& get(array&); template const T& get(const array&); +template T&& get(array&&); } // std @@ -295,6 +296,18 @@ get(const array<_Tp, _Size>& __a) return __a[_Ip]; } +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +_LIBCPP_INLINE_VISIBILITY inline +_Tp&& +get(array<_Tp, _Size>&& __a) +{ + return _STD::move(__a[_Ip]); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + _LIBCPP_END_NAMESPACE_STD #endif // _LIBCPP_ARRAY diff --git a/include/tuple b/include/tuple index e134bdff5..27c16ed51 100644 --- a/include/tuple +++ b/include/tuple @@ -88,6 +88,7 @@ template class tuple_element>; // 20.4.1.5, element access: template typename tuple_element>::type& get(tuple&); template typename tuple_element>::type const& get(const tuple&); +template typename tuple_element>::type&& get(tuple&&); // 20.4.1.6, relational operators: template bool operator==(const tuple&, const tuple&); @@ -430,6 +431,8 @@ class _LIBCPP_VISIBLE tuple typename tuple_element<_Jp, tuple<_Up...>>::type& get(tuple<_Up...>&); template friend const typename tuple_element<_Jp, tuple<_Up...>>::type& get(const tuple<_Up...>&); + template friend + typename tuple_element<_Jp, tuple<_Up...>>::type&& get(tuple<_Up...>&&); public: _LIBCPP_INLINE_VISIBILITY @@ -583,6 +586,15 @@ get(const tuple<_Tp...>& __t) return static_cast&>(__t.base_).get(); } +template +inline _LIBCPP_INLINE_VISIBILITY +typename tuple_element<_Ip, tuple<_Tp...>>::type&& +get(tuple<_Tp...>&& __t) +{ + typedef typename tuple_element<_Ip, tuple<_Tp...>>::type type; + return static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get(); +} + // tie template diff --git a/include/utility b/include/utility index 1faca4571..f4c94bea9 100644 --- a/include/utility +++ b/include/utility @@ -100,6 +100,10 @@ template const typename const tuple_element >::type& get(const std::pair&); +template + typename tuple_element >::type&& + get(std::pair&&); + } // std */ @@ -425,6 +429,16 @@ struct __get_pair<0> _LIBCPP_INLINE_VISIBILITY const _T1& get(const pair<_T1, _T2>& __p) {return __p.first;} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + static + _LIBCPP_INLINE_VISIBILITY + _T1&& + get(pair<_T1, _T2>&& __p) {return _STD::forward<_T1>(__p.first);} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES }; template <> @@ -441,6 +455,16 @@ struct __get_pair<1> _LIBCPP_INLINE_VISIBILITY const _T2& get(const pair<_T1, _T2>& __p) {return __p.second;} + +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + + template + static + _LIBCPP_INLINE_VISIBILITY + _T2&& + get(pair<_T1, _T2>&& __p) {return _STD::forward<_T2>(__p.second);} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES }; template @@ -459,6 +483,18 @@ get(const pair<_T1, _T2>& __p) return __get_pair<_Ip>::get(__p); } +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + +template +_LIBCPP_INLINE_VISIBILITY inline +typename tuple_element<_Ip, pair<_T1, _T2> >::type&& +get(pair<_T1, _T2>&& __p) +{ + return __get_pair<_Ip>::get(_STD::move(__p)); +} + +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES + #endif // _LIBCPP_HAS_NO_VARIADICS _LIBCPP_END_NAMESPACE_STD diff --git a/test/containers/sequences/array/array.tuple/get_rv.pass.cpp b/test/containers/sequences/array/array.tuple/get_rv.pass.cpp new file mode 100644 index 000000000..869c1ec9c --- /dev/null +++ b/test/containers/sequences/array/array.tuple/get_rv.pass.cpp @@ -0,0 +1,29 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// template T&& get(array&& a); + +#include +#include +#include + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef std::unique_ptr T; + typedef std::array C; + C c = {std::unique_ptr(new double(3.5))}; + T t = std::get<0>(std::move(c)); + assert(*t == 3.5); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +} diff --git a/test/utilities/tuple/tuple.tuple/tuple.elem/get_rv.pass.cpp b/test/utilities/tuple/tuple.tuple/tuple.elem/get_rv.pass.cpp new file mode 100644 index 000000000..5a97710c2 --- /dev/null +++ b/test/utilities/tuple/tuple.tuple/tuple.elem/get_rv.pass.cpp @@ -0,0 +1,30 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// template class tuple; + +// template +// typename tuple_element >::type&& +// get(tuple&& t); + +#include +#include +#include + +int main() +{ + { + typedef std::tuple > T; + T t(std::unique_ptr(new int(3))); + std::unique_ptr p = std::get<0>(std::move(t)); + assert(*p == 3); + } +} diff --git a/test/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp b/test/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp new file mode 100644 index 000000000..aa5ca5309 --- /dev/null +++ b/test/utilities/utility/pairs/pair.astuple/get_rv.pass.cpp @@ -0,0 +1,32 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// template struct pair + +// template +// typename tuple_element >::type&& +// get(pair&&); + +#include +#include +#include + +int main() +{ +#ifndef _LIBCPP_HAS_NO_RVALUE_REFERENCES + { + typedef std::pair, short> P; + P p(std::unique_ptr(new int(3)), 4); + std::unique_ptr ptr = std::get<0>(std::move(p)); + assert(*ptr == 3); + } +#endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES +}