Rewrite std::get<Type>(...) helper using constexpr functions.
llvm-svn: 274418
Cr-Mirrored-From: sso://chromium.googlesource.com/_direct/external/github.com/llvm/llvm-project
Cr-Mirrored-Commit: f447e62e1d1007778cfc55c9df2111c8ac104e23
diff --git a/include/tuple b/include/tuple
index 4c9ae42..32f4380 100644
--- a/include/tuple
+++ b/include/tuple
@@ -986,39 +986,39 @@
}
#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 {
+static constexpr size_t __not_found = -1;
+static constexpr size_t __ambiguous = __not_found - 1;
-template <typename _T1, size_t _Idx>
-struct __find_exactly_one_t_helper <_T1, _Idx> {
- static constexpr size_t value = -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 <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 <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