Author: ericwf Date: Fri Jul 1 22:18:30 2016 New Revision: 274418 URL: http://llvm.org/viewvc/llvm-project?rev=274418&view=rev Log: Rewrite std::get<Type>(...) helper using constexpr functions.
Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp Modified: libcxx/trunk/include/tuple Modified: libcxx/trunk/include/tuple URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/tuple?rev=274418&r1=274417&r2=274418&view=diff ============================================================================== --- libcxx/trunk/include/tuple (original) +++ libcxx/trunk/include/tuple Fri Jul 1 22:18:30 2016 @@ -986,39 +986,39 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT } #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; - }; + +namespace __find_detail { + +static constexpr size_t __not_found = -1; +static constexpr size_t __ambiguous = __not_found - 1; + +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) { + return !__matches ? __res : + (__res == __not_found ? __curr_i : __ambiguous); +} + +template <size_t _Nx> +inline _LIBCPP_INLINE_VISIBILITY +constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) { + return __i == _Nx ? __not_found : + __find_idx_return(__i, __find_idx(__i + 1, __matches), __matches[__i]); +} + +template <class _T1, class ..._Args> +struct __find_exactly_one_checked { + static constexpr bool __matches[] = {is_same<_T1, _Args>::value...}; + static constexpr size_t value = __find_detail::__find_idx(0, __matches); + static_assert (value != __not_found, "type not found in type list" ); + static_assert(value != __ambiguous,"type occurs more than once in type list"); +}; + +} // namespace __find_detail; 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" ); - }; +struct __find_exactly_one_t + : public __find_detail::__find_exactly_one_checked<_T1, _Args...> { +}; template <class _T1, class... _Args> inline _LIBCPP_INLINE_VISIBILITY Added: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp?rev=274418&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp (added) +++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.fail.cpp Fri Jul 1 22:18:30 2016 @@ -0,0 +1,35 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++98, c++03, c++11 + +#include <tuple> +#include <string> + +struct UserType {}; + +void test_bad_index() { + std::tuple<long, long, char, std::string, char, UserType, char> t1; + (void)std::get<int>(t1); // expected-error@tuple:* {{type not found}} + (void)std::get<long>(t1); // expected-note {{requested here}} + (void)std::get<char>(t1); // expected-note {{requested here}} + // expected-error@tuple:* 2 {{type occurs more than once}} +} + +void test_bad_return_type() { + typedef std::unique_ptr<int> upint; + std::tuple<upint> t; + upint p = std::get<upint>(t); // expected-error{{deleted copy constructor}} +} + +int main() +{ + test_bad_index(); + test_bad_return_type(); +} Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp?rev=274417&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp (original) +++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type1.fail.cpp (removed) @@ -1,23 +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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <complex> - -#include <cassert> - -int main() -{ - 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 -} Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp?rev=274417&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp (original) +++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type2.fail.cpp (removed) @@ -1,23 +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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <complex> - -#include <cassert> - -int main() -{ - 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 -} Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp?rev=274417&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp (original) +++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type3.fail.cpp (removed) @@ -1,23 +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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <complex> - -#include <cassert> - -int main() -{ - 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) -} Removed: libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp URL: http://llvm.org/viewvc/llvm-project/libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp?rev=274417&view=auto ============================================================================== --- libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp (original) +++ libcxx/trunk/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type4.fail.cpp (removed) @@ -1,23 +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. -// -//===----------------------------------------------------------------------===// - -// UNSUPPORTED: c++98, c++03, c++11 - -#include <tuple> -#include <string> -#include <memory> - -#include <cassert> - -int main() -{ - typedef std::unique_ptr<int> upint; - std::tuple<upint> t(upint(new int(4))); - upint p = std::get<upint>(t); -} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits