[libcxx-commits] [libcxx] [libc++] Remove <tuple> from <variant> (PR #83183)
Nikolas Klauser via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Feb 27 12:55:23 PST 2024
https://github.com/philnik777 created https://github.com/llvm/llvm-project/pull/83183
This moves a utility from `<tuple>` into an implementation detail header and refactors the selection of the variant index type to use.
>From 16cdc0aa3084d42c0db23fd6c30da049e97bcc13 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 27 Feb 2024 21:49:59 +0100
Subject: [PATCH] [libc++] Remove <tuple> from <variant>
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__tuple/find_index.h | 58 +++++++++++++++++++
libcxx/include/tuple | 35 +----------
libcxx/include/variant | 30 +++++-----
.../variant.visit.member/visit.pass.cpp | 1 +
.../visit_return_type.pass.cpp | 1 +
.../variant/variant.visit/visit.pass.cpp | 1 +
.../variant.visit/visit_return_type.pass.cpp | 1 +
8 files changed, 81 insertions(+), 47 deletions(-)
create mode 100644 libcxx/include/__tuple/find_index.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index cafd8c6e00d968..1405674002e35c 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -701,6 +701,7 @@ set(files
__thread/thread.h
__thread/timed_backoff_policy.h
__tree
+ __tuple/find_index.h
__tuple/make_tuple_types.h
__tuple/pair_like.h
__tuple/sfinae_helpers.h
diff --git a/libcxx/include/__tuple/find_index.h b/libcxx/include/__tuple/find_index.h
new file mode 100644
index 00000000000000..7c3f02e2796f93
--- /dev/null
+++ b/libcxx/include/__tuple/find_index.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LIBCPP___TUPLE_FIND_INDEX_H
+#define _LIBCPP___TUPLE_FIND_INDEX_H
+
+#include <__config>
+#include <__type_traits/is_same.h>
+#include <cstddef>
+
+#if _LIBCPP_STD_VER >= 14
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+namespace __find_detail {
+
+static constexpr size_t __not_found = static_cast<size_t>(-1);
+static constexpr size_t __ambiguous = __not_found - 1;
+
+inline _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
+ return __i == _Nx
+ ? __not_found
+ : __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
+}
+
+template <class _T1, class... _Args>
+struct __find_exactly_one_checked {
+ static constexpr bool __matches[sizeof...(_Args)] = {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");
+};
+
+template <class _T1>
+struct __find_exactly_one_checked<_T1> {
+ static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
+};
+
+} // namespace __find_detail
+
+template <typename _T1, typename... _Args>
+struct __find_exactly_one_t : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {};
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP_STD_VER >= 14
+
+#endif // _LIBCPP___TUPLE_FIND_INDEX_H
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index 96cf3be85b76f2..7cbd1362d6d844 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -214,6 +214,7 @@ template <class... Types>
#include <__fwd/tuple.h>
#include <__memory/allocator_arg_t.h>
#include <__memory/uses_allocator.h>
+#include <__tuple/find_index.h>
#include <__tuple/make_tuple_types.h>
#include <__tuple/sfinae_helpers.h>
#include <__tuple/tuple_element.h>
@@ -1094,40 +1095,6 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT {
# if _LIBCPP_STD_VER >= 14
-namespace __find_detail {
-
-static constexpr size_t __not_found = static_cast<size_t>(-1);
-static constexpr size_t __ambiguous = __not_found - 1;
-
-inline _LIBCPP_HIDE_FROM_ABI 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_HIDE_FROM_ABI constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
- return __i == _Nx
- ? __not_found
- : __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
-}
-
-template <class _T1, class... _Args>
-struct __find_exactly_one_checked {
- static constexpr bool __matches[sizeof...(_Args)] = {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");
-};
-
-template <class _T1>
-struct __find_exactly_one_checked<_T1> {
- static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
-};
-
-} // namespace __find_detail
-
-template <typename _T1, typename... _Args>
-struct __find_exactly_one_t : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {};
-
template <class _T1, class... _Args>
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept {
return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);
diff --git a/libcxx/include/variant b/libcxx/include/variant
index 6063739e52c86b..cd027593f52f07 100644
--- a/libcxx/include/variant
+++ b/libcxx/include/variant
@@ -222,13 +222,18 @@ namespace std {
#include <__functional/operations.h>
#include <__functional/unary_function.h>
#include <__memory/addressof.h>
+#include <__tuple/find_index.h>
+#include <__tuple/sfinae_helpers.h>
#include <__type_traits/add_const.h>
#include <__type_traits/add_cv.h>
#include <__type_traits/add_pointer.h>
#include <__type_traits/add_volatile.h>
+#include <__type_traits/common_type.h>
#include <__type_traits/dependent_type.h>
#include <__type_traits/is_array.h>
+#include <__type_traits/is_default_constructible.h>
#include <__type_traits/is_destructible.h>
+#include <__type_traits/is_nothrow_assignable.h>
#include <__type_traits/is_nothrow_move_constructible.h>
#include <__type_traits/is_trivially_copy_assignable.h>
#include <__type_traits/is_trivially_copy_constructible.h>
@@ -243,6 +248,7 @@ namespace std {
#include <__utility/forward.h>
#include <__utility/forward_like.h>
#include <__utility/in_place.h>
+#include <__utility/integer_sequence.h>
#include <__utility/move.h>
#include <__utility/swap.h>
#include <__variant/monostate.h>
@@ -250,7 +256,6 @@ namespace std {
#include <initializer_list>
#include <limits>
#include <new>
-#include <tuple>
#include <version>
// standard-mandated includes
@@ -341,21 +346,20 @@ struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
inline constexpr size_t variant_npos = static_cast<size_t>(-1);
-_LIBCPP_HIDE_FROM_ABI constexpr int __choose_index_type(unsigned int __num_elem) {
- if (__num_elem < numeric_limits<unsigned char>::max())
- return 0;
- if (__num_elem < numeric_limits<unsigned short>::max())
- return 1;
- return 2;
+template <size_t _NumAlternatives>
+_LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() {
+#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+ if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max())
+ return static_cast<unsigned char>(0);
+ else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max())
+ return static_cast<unsigned short>(0);
+ else
+#endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
+ return static_cast<unsigned int>(0);
}
template <size_t _NumAlts>
-using __variant_index_t =
-# ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
- unsigned int;
-# else
- std::tuple_element_t< __choose_index_type(_NumAlts), std::tuple<unsigned char, unsigned short, unsigned int> >;
-# endif
+using __variant_index_t = decltype(std::__choose_index_type<_NumAlts>());
template <class _IndexType>
constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
diff --git a/libcxx/test/std/utilities/variant/variant.visit.member/visit.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit.member/visit.pass.cpp
index 68706d6c32af4f..50e7fc81387abc 100644
--- a/libcxx/test/std/utilities/variant/variant.visit.member/visit.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit.member/visit.pass.cpp
@@ -21,6 +21,7 @@
#include <cassert>
#include <memory>
#include <string>
+#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
diff --git a/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp
index 20472c62fc5f98..b005f303bc4b6c 100644
--- a/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp
@@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <type_traits>
+#include <tuple>
#include <utility>
#include <variant>
diff --git a/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp
index 097b784f2bf2ce..798ce7ded72a60 100644
--- a/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp
@@ -15,6 +15,7 @@
#include <cassert>
#include <memory>
#include <string>
+#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
diff --git a/libcxx/test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp b/libcxx/test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp
index eb425c07f93222..b1189dff656db4 100644
--- a/libcxx/test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp
+++ b/libcxx/test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp
@@ -15,6 +15,7 @@
#include <cassert>
#include <memory>
#include <string>
+#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
More information about the libcxx-commits
mailing list