[libcxx-commits] [libcxx] [libc++] Implement P2819: Add tuple protocol to complex (PR #72776)
via libcxx-commits
libcxx-commits at lists.llvm.org
Sun Nov 19 06:53:40 PST 2023
https://github.com/PragmaTwice updated https://github.com/llvm/llvm-project/pull/72776
>From 3f0679d16016630ad57a830c8c676bc87bc1eeb8 Mon Sep 17 00:00:00 2001
From: PragmaTwice <twice at apache.org>
Date: Sat, 18 Nov 2023 05:51:52 +0900
Subject: [PATCH 1/3] [libc++] Implement P2819: Add tuple protocol to complex
---
libcxx/include/complex | 68 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 68 insertions(+)
diff --git a/libcxx/include/complex b/libcxx/include/complex
index 5cfb160ee00f020..44df42557ea3ca7 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -1538,6 +1538,74 @@ inline namespace literals
} // namespace literals
#endif
+#if _LIBCPP_STD_VER >= 26
+// Tuple interface [complex.tuple]
+template<class _Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_size<complex<_Tp>>
+ : public integral_constant<size_t, 2> {};
+
+template<size_t _Ip, class _Tp>
+struct _LIBCPP_TEMPLATE_VIS tuple_element<_Ip, complex<_Tp>>
+{
+ static_assert(_Ip < 2, "Index out of bounds in std::tuple_element<std::complex<T>>");
+
+ using type _LIBCPP_NODEBUG = _Tp;
+};
+
+template <size_t _Ip>
+struct __get_complex
+{
+ static_assert(_Ip < 2, "Index out of bounds in std::get<std::complex<T>>");
+
+ template <typename _Tp>
+ struct to_array_type;
+
+ template <typename _Tp>
+ struct to_array_type<complex<_Tp>>
+ {
+ using type = _Tp[2];
+ };
+
+ template <class _Tp>
+ static _LIBCPP_HIDE_FROM_ABI constexpr
+ decltype(auto)
+ get(_Tp&& __z) _NOEXCEPT
+ {
+ using _Array_type = typename __get_complex::to_array_type<std::remove_cvref_t<_Tp>>::type;
+ using _Forwarded_array_type = decltype(forward_like<_Tp>(declval<_Array_type>()));
+ return reinterpret_cast<_Forwarded_array_type>(__z)[_Ip];
+ }
+};
+
+template<size_t _Ip, class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI
+constexpr _Tp& get(complex<_Tp>& __z) _NOEXCEPT
+{
+ return __get_complex<_Ip>::get(__z);
+}
+
+template<size_t _Ip, class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI
+constexpr const _Tp& get(const complex<_Tp>& __z) _NOEXCEPT
+{
+ return __get_complex<_Ip>::get(__z);
+}
+
+template<size_t _Ip, class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI
+constexpr _Tp&& get(complex<_Tp>&& __z) _NOEXCEPT
+{
+ return __get_complex<_Ip>::get(std::move(__z));
+}
+
+template<size_t _Ip, class _Tp>
+inline _LIBCPP_HIDE_FROM_ABI
+constexpr const _Tp&& get(const complex<_Tp>&& __z) _NOEXCEPT
+{
+ return __get_complex<_Ip>::get(std::move(__z));
+}
+#endif
+
_LIBCPP_END_NAMESPACE_STD
#if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20
>From 7bca8296a22ffee1ce4729989a418a67227b5c8c Mon Sep 17 00:00:00 2001
From: PragmaTwice <twice at apache.org>
Date: Sat, 18 Nov 2023 16:04:57 +0900
Subject: [PATCH 2/3] use _ForwardLike instead of std::forward_like
---
libcxx/include/complex | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/libcxx/include/complex b/libcxx/include/complex
index 44df42557ea3ca7..c917bdcbc377b3e 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -244,6 +244,16 @@ template<class T> complex<T> tanh (const complex<T>&);
# pragma GCC system_header
#endif
+#if _LIBCPP_STD_VER >= 26
+// Tuple interface [complex.tuple]
+# include <__fwd/get.h>
+# include <__tuple/tuple_element.h>
+# include <__tuple/tuple_size.h>
+# include <__type_traits/remove_cvref.h>
+# include <__type_traits/integral_constant.h>
+# include <__utility/move.h>
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
@@ -1563,7 +1573,7 @@ struct __get_complex
template <typename _Tp>
struct to_array_type<complex<_Tp>>
{
- using type = _Tp[2];
+ using type _LIBCPP_NODEBUG = _Tp[2];
};
template <class _Tp>
@@ -1572,8 +1582,7 @@ struct __get_complex
get(_Tp&& __z) _NOEXCEPT
{
using _Array_type = typename __get_complex::to_array_type<std::remove_cvref_t<_Tp>>::type;
- using _Forwarded_array_type = decltype(forward_like<_Tp>(declval<_Array_type>()));
- return reinterpret_cast<_Forwarded_array_type>(__z)[_Ip];
+ return reinterpret_cast<_ForwardLike<_Tp, _Array_type>>(__z)[_Ip];
}
};
>From fd4f4d9a72823a3e42aac91bd52812cc97fd2baf Mon Sep 17 00:00:00 2001
From: PragmaTwice <twice at apache.org>
Date: Sat, 18 Nov 2023 17:35:00 +0900
Subject: [PATCH 3/3] add complex to tuple_like
---
libcxx/include/CMakeLists.txt | 1 +
libcxx/include/__fwd/complex.h | 25 +++++++++++++++++++++++++
libcxx/include/__tuple/tuple_like.h | 9 +++++++++
libcxx/include/complex | 9 +++++----
4 files changed, 40 insertions(+), 4 deletions(-)
create mode 100644 libcxx/include/__fwd/complex.h
diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt
index 889d7fedbf2965f..7719654b2e18545 100644
--- a/libcxx/include/CMakeLists.txt
+++ b/libcxx/include/CMakeLists.txt
@@ -422,6 +422,7 @@ set(files
__functional/weak_result_type.h
__fwd/array.h
__fwd/bit_reference.h
+ __fwd/complex.h
__fwd/fstream.h
__fwd/get.h
__fwd/hash.h
diff --git a/libcxx/include/__fwd/complex.h b/libcxx/include/__fwd/complex.h
new file mode 100644
index 000000000000000..b8cfbf7daf84858
--- /dev/null
+++ b/libcxx/include/__fwd/complex.h
@@ -0,0 +1,25 @@
+//===---------------------------------------------------------------------===//
+//
+// 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___FWD_COMPLEX_H
+#define _LIBCPP___FWD_COMPLEX_H
+
+#include <__config>
+
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
+_LIBCPP_BEGIN_NAMESPACE_STD
+
+template <class>
+struct _LIBCPP_TEMPLATE_VIS complex;
+
+_LIBCPP_END_NAMESPACE_STD
+
+#endif // _LIBCPP___FWD_COMPLEX_H
diff --git a/libcxx/include/__tuple/tuple_like.h b/libcxx/include/__tuple/tuple_like.h
index dab395be616b7d2..00f8fc818d66c22 100644
--- a/libcxx/include/__tuple/tuple_like.h
+++ b/libcxx/include/__tuple/tuple_like.h
@@ -18,6 +18,10 @@
#include <__type_traits/remove_cvref.h>
#include <cstddef>
+#if _LIBCPP_STD_VER >= 26
+# include <__fwd/complex.h>
+#endif
+
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
#endif
@@ -41,6 +45,11 @@ struct __tuple_like_impl<array<_Tp, _Size> > : true_type {};
template <class _Ip, class _Sp, ranges::subrange_kind _Kp>
struct __tuple_like_impl<ranges::subrange<_Ip, _Sp, _Kp> > : true_type {};
+#if _LIBCPP_STD_VER >= 26
+template <class _Tp>
+struct __tuple_like_impl<complex<_Tp> > : true_type {};
+#endif
+
template <class _Tp>
concept __tuple_like = __tuple_like_impl<remove_cvref_t<_Tp>>::value;
diff --git a/libcxx/include/complex b/libcxx/include/complex
index c917bdcbc377b3e..97e48fb73b2ef83 100644
--- a/libcxx/include/complex
+++ b/libcxx/include/complex
@@ -240,13 +240,10 @@ template<class T> complex<T> tanh (const complex<T>&);
# include <sstream> // for std::basic_ostringstream
#endif
-#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
-# pragma GCC system_header
-#endif
-
#if _LIBCPP_STD_VER >= 26
// Tuple interface [complex.tuple]
# include <__fwd/get.h>
+# include <__fwd/complex.h>
# include <__tuple/tuple_element.h>
# include <__tuple/tuple_size.h>
# include <__type_traits/remove_cvref.h>
@@ -254,6 +251,10 @@ template<class T> complex<T> tanh (const complex<T>&);
# include <__utility/move.h>
#endif
+#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
+# pragma GCC system_header
+#endif
+
_LIBCPP_BEGIN_NAMESPACE_STD
template<class _Tp> class _LIBCPP_TEMPLATE_VIS complex;
More information about the libcxx-commits
mailing list