[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 05:30:37 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/2] [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/2] 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];
   }
 };
 



More information about the libcxx-commits mailing list