diff options
| author | Marshall Clow <mclow.lists@gmail.com> | 2013-07-13 02:54:05 +0000 |
|---|---|---|
| committer | Marshall Clow <mclow.lists@gmail.com> | 2013-07-13 02:54:05 +0000 |
| commit | e99520c72e2906fea3c9ff39d4a46384cdf205f1 (patch) | |
| tree | c5b24f832a8e8ae26151dd80aa2b05c425440999 /libcxx | |
| parent | 95d99308c448cd50596e75ca51286ff1e1f750e2 (diff) | |
| download | bcm5719-llvm-e99520c72e2906fea3c9ff39d4a46384cdf205f1.tar.gz bcm5719-llvm-e99520c72e2906fea3c9ff39d4a46384cdf205f1.zip | |
Implement n3584 - Addressing Tuples by Type
llvm-svn: 186237
Diffstat (limited to 'libcxx')
11 files changed, 387 insertions, 0 deletions
diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 0df315e2aa4..d8a36e6e9f5 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -94,6 +94,13 @@ template <intsize_t I, class... T> typename tuple_element<I, tuple<T...>>::type&& get(tuple<T...>&&) noexcept; +template <class T1, class... T> + constexpr T1& get(tuple<T...>&) noexcept; // C++14 +template <class T1, class... T> + constexpr T1 const& get(const tuple<T...>&) noexcept; // C++14 +template <class T1, class... T> + constexpr T1&& get(tuple<T...>&&) noexcept; // C++14 + // 20.4.1.6, relational operators: template<class... T, class... U> bool operator==(const tuple<T...>&, const tuple<U...>&); template<class... T, class... U> bool operator<(const tuple<T...>&, const tuple<U...>&); @@ -783,6 +790,64 @@ get(tuple<_Tp...>&& __t) _NOEXCEPT static_cast<__tuple_leaf<_Ip, type>&&>(__t.base_).get()); } +#if _LIBCPP_STD_VER > 11 +// get by type +template <typename _T1, size_t _Idx, typename... _Args> +struct __find_exactly_one_t_helper; + +// -- find exactly one +template <typename _T1, size_t _Idx, typename... _Args> +struct __find_exactly_one_t_checker { + static constexpr size_t value = _Idx; +// Check the rest of the list to make sure there's only one + static_assert ( __find_exactly_one_t_helper<_T1, 0, _Args...>::value == -1, "type can only occur once in type list" ); + }; + + +template <typename _T1, size_t _Idx> +struct __find_exactly_one_t_helper <_T1, _Idx> { + static constexpr size_t value = -1; + }; + +template <typename _T1, size_t _Idx, typename _Head, typename... _Args> +struct __find_exactly_one_t_helper <_T1, _Idx, _Head, _Args...> { + static constexpr size_t value = + std::conditional< + std::is_same<_T1, _Head>::value, + __find_exactly_one_t_checker<_T1, _Idx, _Args...>, + __find_exactly_one_t_helper <_T1, _Idx+1, _Args...> + >::type::value; + }; + +template <typename _T1, typename... _Args> +struct __find_exactly_one_t { + static constexpr size_t value = __find_exactly_one_t_helper<_T1, 0, _Args...>::value; + static_assert ( value != -1, "type not found in type list" ); + }; + +template <class _T1, class... _Args> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _T1& get(tuple<_Args...>& __tup) noexcept +{ + return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); +} + +template <class _T1, class... _Args> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _T1 const& get(tuple<_Args...> const& __tup) noexcept +{ + return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup); +} + +template <class _T1, class... _Args> +inline _LIBCPP_INLINE_VISIBILITY +constexpr _T1&& get(tuple<_Args...>&& __tup) noexcept +{ + return _VSTD::get<__find_exactly_one_t<_T1, _Args...>::value>(_VSTD::move<tuple<_Args...>>(__tup)); +} + +#endif + // tie template <class ..._Tp> diff --git a/libcxx/include/utility b/libcxx/include/utility index bea463bbdb0..3e4b401f2d9 100644 --- a/libcxx/include/utility +++ b/libcxx/include/utility @@ -117,6 +117,15 @@ template<size_t I, class T1, class T2> typename tuple_element<I, std::pair<T1, T2> >::type&& get(std::pair<T1, T2>&&) noexcept; +template<class T1, class T2> + constexpr T1& get(std::pair<T1, T2>&) noexcept; // C++14 + +template<size_t I, class T1, class T2> + constexpr T1 const& get(std::pair<T1, T2> const &) noexcept; // C++14 + +template<size_t I, class T1, class T2> + constexpr T1&& get(std::pair<T1, T2>&&) noexcept; // C++14 + // C++14 template<class T, T... I> @@ -602,6 +611,51 @@ get(pair<_T1, _T2>&& __p) _NOEXCEPT #endif // _LIBCPP_HAS_NO_RVALUE_REFERENCES #if _LIBCPP_STD_VER > 11 +template <class _T1, class _T2> +_LIBCPP_INLINE_VISIBILITY inline +constexpr _T1 & get(pair<_T1, _T2>& __p) _NOEXCEPT +{ + return __get_pair<0>::get(__p); +} + +template <class _T1, class _T2> +_LIBCPP_INLINE_VISIBILITY inline +constexpr _T1 const & get(pair<_T1, _T2> const& __p) _NOEXCEPT +{ + return __get_pair<0>::get(__p); +} + +template <class _T1, class _T2> +_LIBCPP_INLINE_VISIBILITY inline +constexpr _T1 && get(pair<_T1, _T2>&& __p) _NOEXCEPT +{ + return __get_pair<0>::get(_VSTD::move(__p)); +} + +template <class _T1, class _T2> +_LIBCPP_INLINE_VISIBILITY inline +constexpr _T1 & get(pair<_T2, _T1>& __p) _NOEXCEPT +{ + return __get_pair<1>::get(__p); +} + +template <class _T1, class _T2> +_LIBCPP_INLINE_VISIBILITY inline +constexpr _T1 const & get(pair<_T2, _T1> const& __p) _NOEXCEPT +{ + return __get_pair<1>::get(__p); +} + +template <class _T1, class _T2> +_LIBCPP_INLINE_VISIBILITY inline +constexpr _T1 && get(pair<_T2, _T1>&& __p) _NOEXCEPT +{ + return __get_pair<1>::get(_VSTD::move(__p)); +} + +#endif + +#if _LIBCPP_STD_VER > 11 template<class _Tp, _Tp... _Ip> struct _LIBCPP_TYPE_VIS integer_sequence diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp new file mode 100644 index 00000000000..1835a9f5284 --- /dev/null +++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.pass.cpp @@ -0,0 +1,52 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <tuple> +#include <string> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + { + auto t1 = std::tuple<int, std::string, cf> { 42, "Hi", { 1,2 }}; + assert ( std::get<int>(t1) == 42 ); // find at the beginning + assert ( std::get<std::string>(t1) == "Hi" ); // find in the middle + assert ( std::get<cf>(t1).real() == 1 ); // find at the end + assert ( std::get<cf>(t1).imag() == 2 ); + } + + { + auto t2 = std::tuple<int, std::string, int, cf> { 42, "Hi", 23, { 1,2 }}; +// get<int> would fail! + assert ( std::get<std::string>(t2) == "Hi" ); + assert (( std::get<cf>(t2) == cf{ 1,2 } )); + } + + { + const std::tuple<int, const int, double, double> p5 { 1, 2, 3.4, 5.6 }; + const int &i1 = std::get<int>(p5); + const int &i2 = std::get<const int>(p5); + assert ( i1 == 1 ); + assert ( i2 == 2 ); + } + + { + typedef std::unique_ptr<int> upint; + std::tuple<upint> t(upint(new int(4))); + upint p = std::get<upint>(std::move(t)); // get rvalue + assert(*p == 4); + assert(std::get<0>(t) == nullptr); // has been moved from + } + +#endif +} diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp new file mode 100644 index 00000000000..094f8090542 --- /dev/null +++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <tuple> +#include <string> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + auto t1 = std::make_tuple<int, std::string> ( 42, "Hi" ); + assert ( std::get<cf>(t1) == cf {1,2} ); // no such type +#else +#error +#endif +} diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp new file mode 100644 index 00000000000..0b2fac04c1a --- /dev/null +++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <tuple> +#include <string> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + auto t1 = std::make_tuple<int, int, std::string, cf> ( 42, 21, "Hi", { 1,2 } ); + assert ( std::get<int>(t1) == 42 ); // two ints here +#else +#error +#endif +} diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp new file mode 100644 index 00000000000..f1881717baa --- /dev/null +++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <tuple> +#include <string> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + auto t1 = std::make_tuple<double, int, std::string, cf, int> ( 42, 21, "Hi", { 1,2 } ); + assert ( std::get<int>(t1) == 42 ); // two ints here (one at the end) +#else +#error +#endif +} diff --git a/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp new file mode 100644 index 00000000000..e78c4f107c2 --- /dev/null +++ b/libcxx/test/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <tuple> +#include <string> +#include <memory> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::unique_ptr<int> upint; + std::tuple<upint> t(upint(new int(4))); + upint p = std::get<upint>(t); +#else +#error +#endif +} diff --git a/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp new file mode 100644 index 00000000000..176d58330d1 --- /dev/null +++ b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type.pass.cpp @@ -0,0 +1,44 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <utility> +#include <string> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + { + auto t1 = std::make_pair<int, cf> ( 42, { 1,2 } ); + assert ( std::get<int>(t1) == 42 ); + assert ( std::get<cf>(t1).real() == 1 ); + assert ( std::get<cf>(t1).imag() == 2 ); + } + + { + const std::pair<int, const int> p1 { 1, 2 }; + const int &i1 = std::get<int>(p1); + const int &i2 = std::get<const int>(p1); + assert ( i1 == 1 ); + assert ( i2 == 2 ); + } + + { + typedef std::unique_ptr<int> upint; + std::pair<upint, int> t(upint(new int(4)), 42); + upint p = std::get<0>(std::move(t)); // get rvalue + assert(*p == 4); + assert(std::get<0>(t) == nullptr); // has been moved from + } + +#endif +} diff --git a/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp new file mode 100644 index 00000000000..1c01ed74dd8 --- /dev/null +++ b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type1.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <utility> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + auto t1 = std::make_pair<int, double> ( 42, 3.4 ); + assert ( std::get<cf>(t1) == cf {1,2} ); // no such type +#else +#error +#endif +} diff --git a/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp new file mode 100644 index 00000000000..f9e3942d7e7 --- /dev/null +++ b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type2.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <utility> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::complex<float> cf; + auto t1 = std::make_pair<int, int> ( 42, 43 ); + assert ( std::get<int>(t1) == 42 ); // two ints +#else +#error +#endif +} diff --git a/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp new file mode 100644 index 00000000000..8bf35c7b312 --- /dev/null +++ b/libcxx/test/utilities/utility/pairs/pair.astuple/pairs.by.type3.fail.cpp @@ -0,0 +1,24 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +#include <utility> +#include <complex> + +#include <cassert> + +int main() +{ +#if _LIBCPP_STD_VER > 11 + typedef std::unique_ptr<int> upint; + std::pair<upint, int> t(upint(new int(4)), 23); + upint p = std::get<upint>(t); +#else +#error +#endif +} |

