Skip to content

Commit

Permalink
[libc++] Remove <tuple> from <variant> (#83183)
Browse files Browse the repository at this point in the history
This moves a utility from `<tuple>` into an implementation detail header
and refactors the selection of the variant index type to use.
  • Loading branch information
philnik777 authored Mar 11, 2024
1 parent 2b8f1da commit 2a38551
Show file tree
Hide file tree
Showing 14 changed files with 98 additions and 59 deletions.
1 change: 1 addition & 0 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 62 additions & 0 deletions libcxx/include/__tuple/find_index.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//===----------------------------------------------------------------------===//
//
// 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 !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif

#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
1 change: 1 addition & 0 deletions libcxx/include/libcxx.imp
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@
{ include: [ "<__thread/this_thread.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/thread.h>", "private", "<thread>", "public" ] },
{ include: [ "<__thread/timed_backoff_policy.h>", "private", "<thread>", "public" ] },
{ include: [ "<__tuple/find_index.h>", "private", "<tuple>", "public" ] },
{ include: [ "<__tuple/make_tuple_types.h>", "private", "<tuple>", "public" ] },
{ include: [ "<__tuple/pair_like.h>", "private", "<tuple>", "public" ] },
{ include: [ "<__tuple/sfinae_helpers.h>", "private", "<tuple>", "public" ] },
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -1799,6 +1799,7 @@ module std_private_thread_thread [system] {
}
module std_private_thread_timed_backoff_policy [system] { header "__thread/timed_backoff_policy.h" }

module std_private_tuple_find_index [system] { header "__tuple/find_index.h" }
module std_private_tuple_make_tuple_types [system] { header "__tuple/make_tuple_types.h" }
module std_private_tuple_pair_like [system] {
header "__tuple/pair_like.h"
Expand Down
35 changes: 1 addition & 34 deletions libcxx/include/tuple
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,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>
Expand Down Expand Up @@ -1087,40 +1088,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);
Expand Down
31 changes: 18 additions & 13 deletions libcxx/include/variant
Original file line number Diff line number Diff line change
Expand Up @@ -221,13 +221,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>
Expand All @@ -242,14 +247,14 @@ 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>
#include <__verbose_abort>
#include <initializer_list>
#include <limits>
#include <new>
#include <tuple>
#include <version>

// standard-mandated includes
Expand Down Expand Up @@ -340,21 +345,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);
Expand Down Expand Up @@ -1625,6 +1629,7 @@ _LIBCPP_POP_MACROS

#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
# include <exception>
# include <tuple>
# include <type_traits>
# include <typeinfo>
# include <utility>
Expand Down
1 change: 0 additions & 1 deletion libcxx/test/libcxx/transitive_includes/cxx23.csv
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,6 @@ variant cstring
variant initializer_list
variant limits
variant new
variant tuple
variant version
vector array
vector cctype
Expand Down
1 change: 0 additions & 1 deletion libcxx/test/libcxx/transitive_includes/cxx26.csv
Original file line number Diff line number Diff line change
Expand Up @@ -661,7 +661,6 @@ variant cstring
variant initializer_list
variant limits
variant new
variant tuple
variant version
vector array
vector cctype
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ void test_index_type() {
template <class IndexType>
void test_index_internals() {
using Lim = std::numeric_limits<IndexType>;
static_assert(std::__choose_index_type(Lim::max() -1) !=
std::__choose_index_type(Lim::max()), "");
static_assert(std::is_same_v<
std::__variant_index_t<Lim::max()-1>,
std::__variant_index_t<Lim::max()>
> == ExpectEqual, "");
using IndexT = std::__variant_index_t<Lim::max()-1>;
#ifdef _LIBCPP_ABI_VARIANT_INDEX_TYPE_OPTIMIZATION
static_assert(!std::is_same_v<decltype(std::__choose_index_type<Lim::max() - 1>()),
decltype(std::__choose_index_type<Lim::max()>())>);
#endif
static_assert(
std::is_same_v<std::__variant_index_t<Lim::max() - 1>, std::__variant_index_t<Lim::max()> > == ExpectEqual, "");
using IndexT = std::__variant_index_t<Lim::max() - 1>;
using IndexLim = std::numeric_limits<IndexT>;
static_assert(std::__variant_npos<IndexT> == IndexLim::max(), "");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ struct UserType {};

void test_bad_index() {
std::tuple<long, long, char, std::string, char, UserType, char> t1;
TEST_IGNORE_NODISCARD std::get<int>(t1); // expected-error@tuple:* {{type not found}}
TEST_IGNORE_NODISCARD std::get<int>(t1); // expected-error@*:* {{type not found}}
TEST_IGNORE_NODISCARD std::get<long>(t1); // expected-note {{requested here}}
TEST_IGNORE_NODISCARD std::get<char>(t1); // expected-note {{requested here}}
// expected-error@tuple:* 2 {{type occurs more than once}}
// expected-error@*:* 2 {{type occurs more than once}}
std::tuple<> t0;
TEST_IGNORE_NODISCARD std::get<char*>(t0); // expected-node {{requested here}}
// expected-error@tuple:* 1 {{type not in empty type list}}
// expected-error@*:* {{type not in empty type list}}
}

void test_bad_return_type() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <cassert>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <memory>
#include <string>
#include <type_traits>
#include <tuple>
#include <utility>
#include <variant>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <cassert>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <cassert>
#include <memory>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
Expand Down

0 comments on commit 2a38551

Please sign in to comment.