diff options
Diffstat (limited to 'libcxx/include/tuple')
-rw-r--r-- | libcxx/include/tuple | 56 |
1 files changed, 28 insertions, 28 deletions
diff --git a/libcxx/include/tuple b/libcxx/include/tuple index 4c9ae42462e..32f43805ff7 100644 --- a/libcxx/include/tuple +++ b/libcxx/include/tuple @@ -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" ); - }; +namespace __find_detail { -template <typename _T1, size_t _Idx> -struct __find_exactly_one_t_helper <_T1, _Idx> { - static constexpr size_t value = -1; - }; +static constexpr size_t __not_found = -1; +static constexpr size_t __ambiguous = __not_found - 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; - }; +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 |