-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[libc++] P1789R3: Library Support for Expansion Statements #167184
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
032858a
7402319
350a3a1
fd296c5
e309910
a795b2c
2a238dc
49c6594
04a6f5f
b9781f4
94909a3
a7ed542
3e3ab8d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -11,6 +11,8 @@ | |||||
|
|
||||||
| #include <__config> | ||||||
| #include <__cstddef/size_t.h> | ||||||
| #include <__tuple/tuple_element.h> | ||||||
| #include <__tuple/tuple_size.h> | ||||||
| #include <__type_traits/is_integral.h> | ||||||
|
|
||||||
| #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER) | ||||||
|
|
@@ -67,6 +69,30 @@ _LIBCPP_HIDE_FROM_ABI constexpr void __for_each_index_sequence(index_sequence<_I | |||||
| } | ||||||
| # endif // _LIBCPP_STD_VER >= 20 | ||||||
|
|
||||||
| # if _LIBCPP_STD_VER >= 26 | ||||||
| // structured binding support for integer_sequence | ||||||
| template <class _Tp, _Tp... _Indices> | ||||||
| struct tuple_size<integer_sequence<_Tp, _Indices...>> : integral_constant<size_t, sizeof...(_Indices)> {}; | ||||||
|
|
||||||
| template <size_t _Ip, class _Tp, _Tp... _Indices> | ||||||
| struct tuple_element<_Ip, integer_sequence<_Tp, _Indices...>> { | ||||||
| static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (std::integer_sequence)"); | ||||||
| using type _LIBCPP_NODEBUG = _Tp; | ||||||
| }; | ||||||
|
|
||||||
| template <size_t _Ip, class _Tp, _Tp... _Indices> | ||||||
| struct tuple_element<_Ip, const integer_sequence<_Tp, _Indices...>> { | ||||||
| static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::tuple_element<> (const std::integer_sequence)"); | ||||||
| using type _LIBCPP_NODEBUG = _Tp; | ||||||
| }; | ||||||
|
|
||||||
| template <size_t _Ip, class _Tp, _Tp... _Indices> | ||||||
| _LIBCPP_HIDE_FROM_ABI constexpr _Tp get(integer_sequence<_Tp, _Indices...>) noexcept { | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think we can mark |
||||||
| static_assert(_Ip < sizeof...(_Indices), "Index out of bounds in std::get<> (std::integer_sequence)"); | ||||||
| return _Indices...[_Ip]; | ||||||
| } | ||||||
| # endif // _LIBCPP_STD_VER >= 26 | ||||||
|
|
||||||
| # endif // _LIBCPP_STD_VER >= 14 | ||||||
|
|
||||||
| _LIBCPP_END_NAMESPACE_STD | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,54 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //===----------------------------------------------------------------------===// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // 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 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| //===----------------------------------------------------------------------===// | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // REQUIRES: std-at-least-c++26 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // <utility> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // template<size_t I, class T, T... Values> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // struct tuple_element<I, integer_sequence<T, Values...>>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // template<size_t I, class T, T... Values> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // struct tuple_element<I, const integer_sequence<T, Values...>>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // template<size_t I, class T, T... Values> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| // constexpr T get(integer_sequence<T, Values...>) noexcept; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+13
to
+18
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think you should rename this file to "general.pass.cpp". |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <cassert> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #include <utility> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void test_structured_bindings() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto [elt0, elt1, elt2, elt3] = std::make_index_sequence<4>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(elt0 == 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(elt1 == 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(elt2 == 2); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(elt3 == 3); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if __cpp_structured_bindings >= 202411L | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We usually guard with a macro
Suggested change
I guess having a TEST_HAS_ macro declared in test_macros.h will be easier to spot and clean-up. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| template <typename...> | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| void test_p1061_structured_bindings() { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto [... empty] = std::make_index_sequence<0>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static_assert(sizeof...(empty) == 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| auto [... size4] = std::make_index_sequence<4>(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| static_assert(sizeof...(size4) == 4); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(size4...[0] == 0); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(size4...[1] == 1); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(size4...[2] == 2); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert(size4...[3] == 3); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| int main(int, char**) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test_structured_bindings(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #if __cpp_structured_bindings >= 202411L | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test_p1061_structured_bindings(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #endif | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return 0; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+23
to
+54
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should test both constant evaluation and runtime behavior. Also, it seems simpler to put the test case for structured binding packs into an immediately invoked lambda expression to avoid duplicated macro guards.
Suggested change
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or maybe just merge the two tests files? WDYT? |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,60 @@ | ||||||||
| //===----------------------------------------------------------------------===// | ||||||||
| // | ||||||||
| // 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 | ||||||||
| // | ||||||||
| //===----------------------------------------------------------------------===// | ||||||||
|
|
||||||||
| // REQUIRES: std-at-least-c++26 | ||||||||
|
|
||||||||
| // <utility> | ||||||||
|
|
||||||||
| // template<class T, T... Values> | ||||||||
| // struct tuple_size<integer_sequence<T, Values...>>; | ||||||||
| // template<size_t I, class T, T... Values> | ||||||||
| // struct tuple_element<I, integer_sequence<T, Values...>>; | ||||||||
| // template<size_t I, class T, T... Values> | ||||||||
| // struct tuple_element<I, const integer_sequence<T, Values...>>; | ||||||||
| // template<size_t I, class T, T... Values> | ||||||||
| // constexpr T get(integer_sequence<T, Values...>) noexcept; | ||||||||
|
|
||||||||
| #include <cassert> | ||||||||
| #include <concepts> | ||||||||
| #include <tuple> | ||||||||
| #include <type_traits> | ||||||||
| #include <utility> | ||||||||
|
|
||||||||
| constexpr void test() { | ||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
I think this won't be necessary if you declare |
||||||||
| // std::tuple_size_v | ||||||||
| using empty = std::integer_sequence<int>; | ||||||||
| static_assert(std::tuple_size_v<empty> == 0); | ||||||||
| static_assert(std::tuple_size_v<const empty> == 0); | ||||||||
|
|
||||||||
| using size4 = std::integer_sequence<int, 9, 8, 7, 2>; | ||||||||
| static_assert(std::tuple_size_v<size4> == 4); | ||||||||
| static_assert(std::tuple_size_v<const size4> == 4); | ||||||||
|
|
||||||||
| // std::tuple_element_t | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<0, size4>, int>); | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<1, size4>, int>); | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<2, size4>, int>); | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<3, size4>, int>); | ||||||||
|
|
||||||||
| static_assert(std::is_same_v<std::tuple_element_t<0, const size4>, int>); | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<1, const size4>, int>); | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<2, const size4>, int>); | ||||||||
| static_assert(std::is_same_v<std::tuple_element_t<3, const size4>, int>); | ||||||||
|
|
||||||||
| // std::get | ||||||||
| constexpr static size4 seq4{}; | ||||||||
Zingam marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
| static_assert(get<0>(seq4) == 9); | ||||||||
Tsche marked this conversation as resolved.
Show resolved
Hide resolved
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||
| static_assert(get<1>(seq4) == 8); | ||||||||
| static_assert(get<2>(seq4) == 7); | ||||||||
| static_assert(get<3>(seq4) == 2); | ||||||||
|
|
||||||||
| static_assert(noexcept(get<0>(seq4))); | ||||||||
|
|
||||||||
| constexpr std::same_as<int> decltype(auto) r = get<0>(seq4); | ||||||||
| static_assert(r == 9); | ||||||||
|
Comment on lines
+58
to
+59
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can replace line 51 with this one as they are doing the same test.
Suggested change
|
||||||||
| } | ||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| //===----------------------------------------------------------------------===// | ||
| // | ||
| // 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 | ||
| // | ||
| //===----------------------------------------------------------------------===// | ||
|
|
||
| // REQUIRES: std-at-least-c++26 | ||
|
|
||
| // <utility> | ||
|
|
||
| // template<size_t I, class T, T... Values> | ||
| // struct tuple_element<I, integer_sequence<T, Values...>>; | ||
| // template<size_t I, class T, T... Values> | ||
| // struct tuple_element<I, const integer_sequence<T, Values...>>; | ||
| // template<size_t I, class T, T... Values> | ||
| // constexpr T get(integer_sequence<T, Values...>) noexcept; | ||
|
|
||
| // Expect failures for tuple_element and get with empty integer_sequence | ||
|
|
||
| #include <utility> | ||
|
|
||
| void f() { | ||
| // expected-error-re@*:* {{static assertion failed{{.*}}Index out of bounds in std::tuple_element<> (std::integer_sequence)}} | ||
| using test1 = std::tuple_element_t<0, std::integer_sequence<int>>; | ||
| // expected-error-re@*:* {{static assertion failed{{.*}}Index out of bounds in std::tuple_element<> (const std::integer_sequence)}} | ||
| using test2 = std::tuple_element_t<0, const std::integer_sequence<int>>; | ||
|
|
||
| auto empty = std::integer_sequence<int>(); | ||
| // expected-error-re@*:* {{static assertion failed{{.*}}Index out of bounds in std::get<> (std::integer_sequence)}} | ||
| // expected-error-re@*:* {{invalid index 0 for pack {{.*}} of size 0}} | ||
| (void)std::get<0>(empty); | ||
Zingam marked this conversation as resolved.
Show resolved
Hide resolved
Comment on lines
+30
to
+33
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: |
||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: