Skip to content

Commit 2a38551

Browse files
authored
[libc++] Remove <tuple> from <variant> (#83183)
This moves a utility from `<tuple>` into an implementation detail header and refactors the selection of the variant index type to use.
1 parent 2b8f1da commit 2a38551

File tree

14 files changed

+98
-59
lines changed

14 files changed

+98
-59
lines changed

libcxx/include/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,7 @@ set(files
701701
__thread/thread.h
702702
__thread/timed_backoff_policy.h
703703
__tree
704+
__tuple/find_index.h
704705
__tuple/make_tuple_types.h
705706
__tuple/pair_like.h
706707
__tuple/sfinae_helpers.h

libcxx/include/__tuple/find_index.h

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef _LIBCPP___TUPLE_FIND_INDEX_H
10+
#define _LIBCPP___TUPLE_FIND_INDEX_H
11+
12+
#include <__config>
13+
#include <__type_traits/is_same.h>
14+
#include <cstddef>
15+
16+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
17+
# pragma GCC system_header
18+
#endif
19+
20+
#if _LIBCPP_STD_VER >= 14
21+
22+
_LIBCPP_BEGIN_NAMESPACE_STD
23+
24+
namespace __find_detail {
25+
26+
static constexpr size_t __not_found = static_cast<size_t>(-1);
27+
static constexpr size_t __ambiguous = __not_found - 1;
28+
29+
inline _LIBCPP_HIDE_FROM_ABI constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
30+
return !__matches ? __res : (__res == __not_found ? __curr_i : __ambiguous);
31+
}
32+
33+
template <size_t _Nx>
34+
inline _LIBCPP_HIDE_FROM_ABI constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
35+
return __i == _Nx
36+
? __not_found
37+
: __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
38+
}
39+
40+
template <class _T1, class... _Args>
41+
struct __find_exactly_one_checked {
42+
static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
43+
static constexpr size_t value = __find_detail::__find_idx(0, __matches);
44+
static_assert(value != __not_found, "type not found in type list");
45+
static_assert(value != __ambiguous, "type occurs more than once in type list");
46+
};
47+
48+
template <class _T1>
49+
struct __find_exactly_one_checked<_T1> {
50+
static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
51+
};
52+
53+
} // namespace __find_detail
54+
55+
template <typename _T1, typename... _Args>
56+
struct __find_exactly_one_t : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {};
57+
58+
_LIBCPP_END_NAMESPACE_STD
59+
60+
#endif // _LIBCPP_STD_VER >= 14
61+
62+
#endif // _LIBCPP___TUPLE_FIND_INDEX_H

libcxx/include/libcxx.imp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,7 @@
697697
{ include: [ "<__thread/this_thread.h>", "private", "<thread>", "public" ] },
698698
{ include: [ "<__thread/thread.h>", "private", "<thread>", "public" ] },
699699
{ include: [ "<__thread/timed_backoff_policy.h>", "private", "<thread>", "public" ] },
700+
{ include: [ "<__tuple/find_index.h>", "private", "<tuple>", "public" ] },
700701
{ include: [ "<__tuple/make_tuple_types.h>", "private", "<tuple>", "public" ] },
701702
{ include: [ "<__tuple/pair_like.h>", "private", "<tuple>", "public" ] },
702703
{ include: [ "<__tuple/sfinae_helpers.h>", "private", "<tuple>", "public" ] },

libcxx/include/module.modulemap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1799,6 +1799,7 @@ module std_private_thread_thread [system] {
17991799
}
18001800
module std_private_thread_timed_backoff_policy [system] { header "__thread/timed_backoff_policy.h" }
18011801

1802+
module std_private_tuple_find_index [system] { header "__tuple/find_index.h" }
18021803
module std_private_tuple_make_tuple_types [system] { header "__tuple/make_tuple_types.h" }
18031804
module std_private_tuple_pair_like [system] {
18041805
header "__tuple/pair_like.h"

libcxx/include/tuple

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ template <class... Types>
213213
#include <__fwd/tuple.h>
214214
#include <__memory/allocator_arg_t.h>
215215
#include <__memory/uses_allocator.h>
216+
#include <__tuple/find_index.h>
216217
#include <__tuple/make_tuple_types.h>
217218
#include <__tuple/sfinae_helpers.h>
218219
#include <__tuple/tuple_element.h>
@@ -1087,40 +1088,6 @@ get(const tuple<_Tp...>&& __t) _NOEXCEPT {
10871088

10881089
# if _LIBCPP_STD_VER >= 14
10891090

1090-
namespace __find_detail {
1091-
1092-
static constexpr size_t __not_found = static_cast<size_t>(-1);
1093-
static constexpr size_t __ambiguous = __not_found - 1;
1094-
1095-
inline _LIBCPP_HIDE_FROM_ABI constexpr size_t __find_idx_return(size_t __curr_i, size_t __res, bool __matches) {
1096-
return !__matches ? __res : (__res == __not_found ? __curr_i : __ambiguous);
1097-
}
1098-
1099-
template <size_t _Nx>
1100-
inline _LIBCPP_HIDE_FROM_ABI constexpr size_t __find_idx(size_t __i, const bool (&__matches)[_Nx]) {
1101-
return __i == _Nx
1102-
? __not_found
1103-
: __find_detail::__find_idx_return(__i, __find_detail::__find_idx(__i + 1, __matches), __matches[__i]);
1104-
}
1105-
1106-
template <class _T1, class... _Args>
1107-
struct __find_exactly_one_checked {
1108-
static constexpr bool __matches[sizeof...(_Args)] = {is_same<_T1, _Args>::value...};
1109-
static constexpr size_t value = __find_detail::__find_idx(0, __matches);
1110-
static_assert(value != __not_found, "type not found in type list");
1111-
static_assert(value != __ambiguous, "type occurs more than once in type list");
1112-
};
1113-
1114-
template <class _T1>
1115-
struct __find_exactly_one_checked<_T1> {
1116-
static_assert(!is_same<_T1, _T1>::value, "type not in empty type list");
1117-
};
1118-
1119-
} // namespace __find_detail
1120-
1121-
template <typename _T1, typename... _Args>
1122-
struct __find_exactly_one_t : public __find_detail::__find_exactly_one_checked<_T1, _Args...> {};
1123-
11241091
template <class _T1, class... _Args>
11251092
inline _LIBCPP_HIDE_FROM_ABI constexpr _T1& get(tuple<_Args...>& __tup) noexcept {
11261093
return std::get<__find_exactly_one_t<_T1, _Args...>::value>(__tup);

libcxx/include/variant

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,13 +221,18 @@ namespace std {
221221
#include <__functional/operations.h>
222222
#include <__functional/unary_function.h>
223223
#include <__memory/addressof.h>
224+
#include <__tuple/find_index.h>
225+
#include <__tuple/sfinae_helpers.h>
224226
#include <__type_traits/add_const.h>
225227
#include <__type_traits/add_cv.h>
226228
#include <__type_traits/add_pointer.h>
227229
#include <__type_traits/add_volatile.h>
230+
#include <__type_traits/common_type.h>
228231
#include <__type_traits/dependent_type.h>
229232
#include <__type_traits/is_array.h>
233+
#include <__type_traits/is_default_constructible.h>
230234
#include <__type_traits/is_destructible.h>
235+
#include <__type_traits/is_nothrow_assignable.h>
231236
#include <__type_traits/is_nothrow_move_constructible.h>
232237
#include <__type_traits/is_trivially_copy_assignable.h>
233238
#include <__type_traits/is_trivially_copy_constructible.h>
@@ -242,14 +247,14 @@ namespace std {
242247
#include <__utility/forward.h>
243248
#include <__utility/forward_like.h>
244249
#include <__utility/in_place.h>
250+
#include <__utility/integer_sequence.h>
245251
#include <__utility/move.h>
246252
#include <__utility/swap.h>
247253
#include <__variant/monostate.h>
248254
#include <__verbose_abort>
249255
#include <initializer_list>
250256
#include <limits>
251257
#include <new>
252-
#include <tuple>
253258
#include <version>
254259

255260
// standard-mandated includes
@@ -340,21 +345,20 @@ struct _LIBCPP_TEMPLATE_VIS variant_alternative<_Ip, variant<_Types...>> {
340345

341346
inline constexpr size_t variant_npos = static_cast<size_t>(-1);
342347

343-
_LIBCPP_HIDE_FROM_ABI constexpr int __choose_index_type(unsigned int __num_elem) {
344-
if (__num_elem < numeric_limits<unsigned char>::max())
345-
return 0;
346-
if (__num_elem < numeric_limits<unsigned short>::max())
347-
return 1;
348-
return 2;
348+
template <size_t _NumAlternatives>
349+
_LIBCPP_HIDE_FROM_ABI constexpr auto __choose_index_type() {
350+
#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
351+
if constexpr (_NumAlternatives < numeric_limits<unsigned char>::max())
352+
return static_cast<unsigned char>(0);
353+
else if constexpr (_NumAlternatives < numeric_limits<unsigned short>::max())
354+
return static_cast<unsigned short>(0);
355+
else
356+
#endif // _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
357+
return static_cast<unsigned int>(0);
349358
}
350359

351360
template <size_t _NumAlts>
352-
using __variant_index_t =
353-
# ifndef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
354-
unsigned int;
355-
# else
356-
std::tuple_element_t< __choose_index_type(_NumAlts), std::tuple<unsigned char, unsigned short, unsigned int> >;
357-
# endif
361+
using __variant_index_t = decltype(std::__choose_index_type<_NumAlts>());
358362

359363
template <class _IndexType>
360364
constexpr _IndexType __variant_npos = static_cast<_IndexType>(-1);
@@ -1625,6 +1629,7 @@ _LIBCPP_POP_MACROS
16251629

16261630
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
16271631
# include <exception>
1632+
# include <tuple>
16281633
# include <type_traits>
16291634
# include <typeinfo>
16301635
# include <utility>

libcxx/test/libcxx/transitive_includes/cxx23.csv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@ variant cstring
661661
variant initializer_list
662662
variant limits
663663
variant new
664-
variant tuple
665664
variant version
666665
vector array
667666
vector cctype

libcxx/test/libcxx/transitive_includes/cxx26.csv

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,6 @@ variant cstring
661661
variant initializer_list
662662
variant limits
663663
variant new
664-
variant tuple
665664
variant version
666665
vector array
667666
vector cctype

libcxx/test/libcxx/utilities/variant/variant.variant/variant_size.pass.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ void test_index_type() {
4949
template <class IndexType>
5050
void test_index_internals() {
5151
using Lim = std::numeric_limits<IndexType>;
52-
static_assert(std::__choose_index_type(Lim::max() -1) !=
53-
std::__choose_index_type(Lim::max()), "");
54-
static_assert(std::is_same_v<
55-
std::__variant_index_t<Lim::max()-1>,
56-
std::__variant_index_t<Lim::max()>
57-
> == ExpectEqual, "");
58-
using IndexT = std::__variant_index_t<Lim::max()-1>;
52+
#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
53+
static_assert(!std::is_same_v<decltype(std::__choose_index_type<Lim::max() - 1>()),
54+
decltype(std::__choose_index_type<Lim::max()>())>);
55+
#endif
56+
static_assert(
57+
std::is_same_v<std::__variant_index_t<Lim::max() - 1>, std::__variant_index_t<Lim::max()> > == ExpectEqual, "");
58+
using IndexT = std::__variant_index_t<Lim::max() - 1>;
5959
using IndexLim = std::numeric_limits<IndexT>;
6060
static_assert(std::__variant_npos<IndexT> == IndexLim::max(), "");
6161
}

libcxx/test/std/utilities/tuple/tuple.tuple/tuple.elem/tuple.by.type.verify.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ struct UserType {};
1818

1919
void test_bad_index() {
2020
std::tuple<long, long, char, std::string, char, UserType, char> t1;
21-
TEST_IGNORE_NODISCARD std::get<int>(t1); // expected-error@tuple:* {{type not found}}
21+
TEST_IGNORE_NODISCARD std::get<int>(t1); // expected-error@*:* {{type not found}}
2222
TEST_IGNORE_NODISCARD std::get<long>(t1); // expected-note {{requested here}}
2323
TEST_IGNORE_NODISCARD std::get<char>(t1); // expected-note {{requested here}}
24-
// expected-error@tuple:* 2 {{type occurs more than once}}
24+
// expected-error@*:* 2 {{type occurs more than once}}
2525
std::tuple<> t0;
2626
TEST_IGNORE_NODISCARD std::get<char*>(t0); // expected-node {{requested here}}
27-
// expected-error@tuple:* 1 {{type not in empty type list}}
27+
// expected-error@*:* {{type not in empty type list}}
2828
}
2929

3030
void test_bad_return_type() {

libcxx/test/std/utilities/variant/variant.visit.member/visit.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include <cassert>
2222
#include <memory>
2323
#include <string>
24+
#include <tuple>
2425
#include <type_traits>
2526
#include <utility>
2627
#include <variant>

libcxx/test/std/utilities/variant/variant.visit.member/visit_return_type.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <memory>
2323
#include <string>
2424
#include <type_traits>
25+
#include <tuple>
2526
#include <utility>
2627
#include <variant>
2728

libcxx/test/std/utilities/variant/variant.visit/visit.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cassert>
1616
#include <memory>
1717
#include <string>
18+
#include <tuple>
1819
#include <type_traits>
1920
#include <utility>
2021
#include <variant>

libcxx/test/std/utilities/variant/variant.visit/visit_return_type.pass.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <cassert>
1616
#include <memory>
1717
#include <string>
18+
#include <tuple>
1819
#include <type_traits>
1920
#include <utility>
2021
#include <variant>

0 commit comments

Comments
 (0)