diff options
author | Hristo Hristov <hghristov.rmm@gmail.com> | 2024-02-19 09:56:06 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-19 09:56:06 +0200 |
commit | 2ea5d167ae43bed5a511d5d819ae7c52cc76ec5c (patch) | |
tree | 01d1cc2d7f8f39aa4f9841ef35b780cf1171ceb4 /libcxx | |
parent | 9d3d6ec665d6284b6ba8c51a57a4a618d67a1697 (diff) | |
download | llvm-2ea5d167ae43bed5a511d5d819ae7c52cc76ec5c.zip llvm-2ea5d167ae43bed5a511d5d819ae7c52cc76ec5c.tar.gz llvm-2ea5d167ae43bed5a511d5d819ae7c52cc76ec5c.tar.bz2 |
[libc++][complex] P2819R2: Add `tuple` protocol to `complex` (#79744)
Implements: P2819R2 <https://wg21.link/P2819R2>
- https://eel.is/c++draft/utilities#concept:tuple-like
- https://eel.is/c++draft/complex.syn
- https://eel.is/c++draft/complex.tuple
---------
Co-authored-by: Zingam <zingam@outlook.com>
Diffstat (limited to 'libcxx')
24 files changed, 622 insertions, 2 deletions
diff --git a/libcxx/docs/ReleaseNotes/19.rst b/libcxx/docs/ReleaseNotes/19.rst index 908d46b..a7f108c 100644 --- a/libcxx/docs/ReleaseNotes/19.rst +++ b/libcxx/docs/ReleaseNotes/19.rst @@ -40,6 +40,7 @@ Implemented Papers - P2637R3 - Member ``visit`` - P2652R2 - Disallow User Specialization of ``allocator_traits`` +- P2819R2 - Add ``tuple`` protocol to ``complex`` Improvements and New Features diff --git a/libcxx/docs/Status/Cxx2cPapers.csv b/libcxx/docs/Status/Cxx2cPapers.csv index a62faee..1c895f7 100644 --- a/libcxx/docs/Status/Cxx2cPapers.csv +++ b/libcxx/docs/Status/Cxx2cPapers.csv @@ -39,7 +39,7 @@ "`P2868R3 <https://wg21.link/P2868R3>`__","LWG","Remove Deprecated ``std::allocator`` Typedef From C++26","Kona November 2023","|Complete|","18.0","" "`P2870R3 <https://wg21.link/P2870R3>`__","LWG","Remove ``basic_string::reserve()`` From C++26","Kona November 2023","|Complete|","18.0","" "`P2871R3 <https://wg21.link/P2871R3>`__","LWG","Remove Deprecated Unicode Conversion Facets from C++26","Kona November 2023","|Complete|","18.0","" -"`P2819R2 <https://wg21.link/P2819R2>`__","LWG","Add tuple protocol to complex","Kona November 2023","","","" +"`P2819R2 <https://wg21.link/P2819R2>`__","LWG","Add tuple protocol to complex","Kona November 2023","|Complete|","19.0","" "`P2937R0 <https://wg21.link/P2937R0>`__","LWG","Freestanding: Remove ``strtok``","Kona November 2023","","","" "`P2833R2 <https://wg21.link/P2833R2>`__","LWG","Freestanding Library: inout expected span","Kona November 2023","","","" "`P2836R1 <https://wg21.link/P2836R1>`__","LWG","``std::basic_const_iterator`` should follow its underlying type's convertibility","Kona November 2023","","","|DR|" diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index fa3b464..cafd8c6 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -429,6 +429,7 @@ set(files __functional/weak_result_type.h __fwd/array.h __fwd/bit_reference.h + __fwd/complex.h __fwd/fstream.h __fwd/hash.h __fwd/ios.h diff --git a/libcxx/include/__fwd/complex.h b/libcxx/include/__fwd/complex.h new file mode 100644 index 0000000..22c78c5 --- /dev/null +++ b/libcxx/include/__fwd/complex.h @@ -0,0 +1,42 @@ +//===---------------------------------------------------------------------===// +// +// 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> +#include <cstddef> + +#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; + +#if _LIBCPP_STD_VER >= 26 + +template <size_t _Ip, class _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp& get(complex<_Tp>&) noexcept; + +template <size_t _Ip, class _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr _Tp&& get(complex<_Tp>&&) noexcept; + +template <size_t _Ip, class _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr const _Tp& get(const complex<_Tp>&) noexcept; + +template <size_t _Ip, class _Tp> +_LIBCPP_HIDE_FROM_ABI constexpr const _Tp&& get(const complex<_Tp>&&) noexcept; + +#endif // _LIBCPP_STD_VER >= 26 + +_LIBCPP_END_NAMESPACE_STD + +#endif // _LIBCPP___FWD_COMPLEX_H diff --git a/libcxx/include/__ranges/elements_view.h b/libcxx/include/__ranges/elements_view.h index 3f35e93..f159f53 100644 --- a/libcxx/include/__ranges/elements_view.h +++ b/libcxx/include/__ranges/elements_view.h @@ -16,6 +16,7 @@ #include <__concepts/derived_from.h> #include <__concepts/equality_comparable.h> #include <__config> +#include <__fwd/complex.h> #include <__iterator/concepts.h> #include <__iterator/iterator_traits.h> #include <__ranges/access.h> diff --git a/libcxx/include/__tuple/tuple_like.h b/libcxx/include/__tuple/tuple_like.h index 3548af9..967e4a5 100644 --- a/libcxx/include/__tuple/tuple_like.h +++ b/libcxx/include/__tuple/tuple_like.h @@ -11,6 +11,7 @@ #include <__config> #include <__fwd/array.h> +#include <__fwd/complex.h> #include <__fwd/pair.h> #include <__fwd/subrange.h> #include <__fwd/tuple.h> @@ -40,6 +41,13 @@ 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 02b9db8..0aba60e 100644 --- a/libcxx/include/complex +++ b/libcxx/include/complex @@ -227,12 +227,41 @@ template<class T> complex<T> sqrt (const complex<T>&); template<class T> complex<T> tan (const complex<T>&); template<class T> complex<T> tanh (const complex<T>&); + // [complex.tuple], tuple interface + template<class T> struct tuple_size; // Since C++26 + template<size_t I, class T> struct tuple_element; // Since C++26 + template<class T> struct tuple_size<complex<T>>; // Since C++26 + template<size_t I, class T> struct tuple_element<I, complex<T>>; // Since C++26 + template<size_t I, class T> + constexpr T& get(complex<T>&) noexcept; // Since C++26 + template<size_t I, class T> + constexpr T&& get(complex<T>&&) noexcept; // Since C++26 + template<size_t I, class T> + constexpr const T& get(const complex<T>&) noexcept; // Since C++26 + template<size_t I, class T> + constexpr const T&& get(const complex<T>&&) noexcept; // Since C++26 + + // [complex.literals], complex literals + inline namespace literals { + inline namespace complex_literals { + constexpr complex<long double> operator""il(long double); // Since C++14 + constexpr complex<long double> operator""il(unsigned long long); // Since C++14 + constexpr complex<double> operator""i(long double); // Since C++14 + constexpr complex<double> operator""i(unsigned long long); // Since C++14 + constexpr complex<float> operator""if(long double); // Since C++14 + constexpr complex<float> operator""if(unsigned long long); // Since C++14 + } + } } // std */ #include <__assert> // all public C++ headers provide the assertion handler #include <__config> +#include <__fwd/complex.h> +#include <__tuple/tuple_element.h> +#include <__tuple/tuple_size.h> +#include <__utility/move.h> #include <cmath> #include <version> @@ -244,6 +273,9 @@ template<class T> complex<T> tanh (const complex<T>&); # pragma GCC system_header #endif +_LIBCPP_PUSH_MACROS +#include <__undef_macros> + _LIBCPP_BEGIN_NAMESPACE_STD template <class _Tp> @@ -331,6 +363,20 @@ public: *this = *this / complex(__c.real(), __c.imag()); return *this; } + +#if _LIBCPP_STD_VER >= 26 + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; +#endif }; template <> @@ -408,6 +454,20 @@ public: *this = *this / complex(__c.real(), __c.imag()); return *this; } + +#if _LIBCPP_STD_VER >= 26 + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; +#endif }; template <> @@ -480,6 +540,20 @@ public: *this = *this / complex(__c.real(), __c.imag()); return *this; } + +#if _LIBCPP_STD_VER >= 26 + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; +#endif }; template <> @@ -553,6 +627,20 @@ public: *this = *this / complex(__c.real(), __c.imag()); return *this; } + +#if _LIBCPP_STD_VER >= 26 + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>&) noexcept; + + template <size_t _Ip, class _Xp> + friend _LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&&) noexcept; +#endif }; inline _LIBCPP_CONSTEXPR complex<float>::complex(const complex<double>& __c) : __re_(__c.real()), __im_(__c.imag()) {} @@ -1352,6 +1440,67 @@ operator<<(basic_ostream<_CharT, _Traits>& __os, const complex<_Tp>& __x) { } #endif // !_LIBCPP_HAS_NO_LOCALIZATION +#if _LIBCPP_STD_VER >= 26 + +// [complex.tuple], tuple interface + +template <class _Tp> +struct tuple_size; + +template <class _Tp> +struct tuple_size<complex<_Tp>> : integral_constant<size_t, 2> {}; + +template <size_t _Ip, class _Tp> +struct tuple_element; + +template <size_t _Ip, class _Tp> +struct tuple_element<_Ip, complex<_Tp>> { + static_assert(_Ip < 2, "Index value is out of range."); + using type = _Tp; +}; + +template <size_t _Ip, class _Xp> +_LIBCPP_HIDE_FROM_ABI constexpr _Xp& get(complex<_Xp>& __z) noexcept { + static_assert(_Ip < 2, "Index value is out of range."); + if constexpr (_Ip == 0) { + return __z.__re_; + } else { + return __z.__im_; + } +} + +template <size_t _Ip, class _Xp> +_LIBCPP_HIDE_FROM_ABI constexpr _Xp&& get(complex<_Xp>&& __z) noexcept { + static_assert(_Ip < 2, "Index value is out of range."); + if constexpr (_Ip == 0) { + return std::move(__z.__re_); + } else { + return std::move(__z.__im_); + } +} + +template <size_t _Ip, class _Xp> +_LIBCPP_HIDE_FROM_ABI constexpr const _Xp& get(const complex<_Xp>& __z) noexcept { + static_assert(_Ip < 2, "Index value is out of range."); + if constexpr (_Ip == 0) { + return __z.__re_; + } else { + return __z.__im_; + } +} + +template <size_t _Ip, class _Xp> +_LIBCPP_HIDE_FROM_ABI constexpr const _Xp&& get(const complex<_Xp>&& __z) noexcept { + static_assert(_Ip < 2, "Index value is out of range."); + if constexpr (_Ip == 0) { + return std::move(__z.__re_); + } else { + return std::move(__z.__im_); + } +} + +#endif // _LIBCPP_STD_VER >= 26 + #if _LIBCPP_STD_VER >= 14 // Literal suffix for complex number literals [complex.literals] inline namespace literals { @@ -1383,6 +1532,8 @@ _LIBCPP_HIDE_FROM_ABI inline constexpr complex<float> operator""if(unsigned long _LIBCPP_END_NAMESPACE_STD +_LIBCPP_POP_MACROS + #if !defined(_LIBCPP_REMOVE_TRANSITIVE_INCLUDES) && _LIBCPP_STD_VER <= 20 # include <iosfwd> # include <stdexcept> diff --git a/libcxx/include/libcxx.imp b/libcxx/include/libcxx.imp index fbe09fa..22fbea9 100644 --- a/libcxx/include/libcxx.imp +++ b/libcxx/include/libcxx.imp @@ -424,6 +424,7 @@ { include: [ "<__fwd/array.h>", "private", "<array>", "public" ] }, { include: [ "<__fwd/bit_reference.h>", "private", "<bitset>", "public" ] }, { include: [ "<__fwd/bit_reference.h>", "private", "<vector>", "public" ] }, + { include: [ "<__fwd/complex.h>", "private", "<complex>", "public" ] }, { include: [ "<__fwd/fstream.h>", "private", "<fstream>", "public" ] }, { include: [ "<__fwd/hash.h>", "private", "<functional>", "public" ] }, { include: [ "<__fwd/ios.h>", "private", "<ios>", "public" ] }, diff --git a/libcxx/include/module.modulemap.in b/libcxx/include/module.modulemap.in index e72136a..219906a 100644 --- a/libcxx/include/module.modulemap.in +++ b/libcxx/include/module.modulemap.in @@ -1195,6 +1195,8 @@ module std_private_compare_synth_three_way [system] { header "__c module std_private_compare_three_way_comparable [system] { header "__compare/three_way_comparable.h" } module std_private_compare_weak_order [system] { header "__compare/weak_order.h" } +module std_private_complex_complex_fwd [system] { header "__fwd/complex.h" } + module std_private_concepts_arithmetic [system] { header "__concepts/arithmetic.h" } module std_private_concepts_assignable [system] { header "__concepts/assignable.h" } module std_private_concepts_boolean_testable [system] { header "__concepts/boolean_testable.h" } diff --git a/libcxx/modules/std/complex.inc b/libcxx/modules/std/complex.inc index 3ccf44f..47a4442 100644 --- a/libcxx/modules/std/complex.inc +++ b/libcxx/modules/std/complex.inc @@ -59,6 +59,13 @@ export namespace std { using std::tan; using std::tanh; +#if _LIBCPP_STD_VER >= 26 + // [complex.tuple], tuple interface + using std::get; + using std::tuple_element; + using std::tuple_size; +#endif + // [complex.literals], complex literals inline namespace literals { inline namespace complex_literals { diff --git a/libcxx/test/libcxx/transitive_includes/cxx03.csv b/libcxx/test/libcxx/transitive_includes/cxx03.csv index caeb0f6..0acc48c8 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx03.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx03.csv @@ -159,6 +159,7 @@ compare limits compare type_traits compare version complex cmath +complex cstddef complex iosfwd complex sstream complex stdexcept diff --git a/libcxx/test/libcxx/transitive_includes/cxx11.csv b/libcxx/test/libcxx/transitive_includes/cxx11.csv index fe0d95b..d2acb13 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx11.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx11.csv @@ -160,6 +160,7 @@ compare limits compare type_traits compare version complex cmath +complex cstddef complex iosfwd complex sstream complex stdexcept diff --git a/libcxx/test/libcxx/transitive_includes/cxx14.csv b/libcxx/test/libcxx/transitive_includes/cxx14.csv index 1ad62ef..ccba63f 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx14.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx14.csv @@ -160,6 +160,7 @@ compare limits compare type_traits compare version complex cmath +complex cstddef complex iosfwd complex sstream complex stdexcept diff --git a/libcxx/test/libcxx/transitive_includes/cxx17.csv b/libcxx/test/libcxx/transitive_includes/cxx17.csv index 1ad62ef..ccba63f 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx17.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx17.csv @@ -160,6 +160,7 @@ compare limits compare type_traits compare version complex cmath +complex cstddef complex iosfwd complex sstream complex stdexcept diff --git a/libcxx/test/libcxx/transitive_includes/cxx20.csv b/libcxx/test/libcxx/transitive_includes/cxx20.csv index e5bfe13..aa9239b 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx20.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx20.csv @@ -166,6 +166,7 @@ compare limits compare type_traits compare version complex cmath +complex cstddef complex iosfwd complex sstream complex stdexcept diff --git a/libcxx/test/libcxx/transitive_includes/cxx23.csv b/libcxx/test/libcxx/transitive_includes/cxx23.csv index c398cea..44b5f78 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx23.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx23.csv @@ -111,6 +111,7 @@ compare cstdint compare limits compare version complex cmath +complex cstddef complex sstream complex version concepts cstddef diff --git a/libcxx/test/libcxx/transitive_includes/cxx26.csv b/libcxx/test/libcxx/transitive_includes/cxx26.csv index c398cea..44b5f78 100644 --- a/libcxx/test/libcxx/transitive_includes/cxx26.csv +++ b/libcxx/test/libcxx/transitive_includes/cxx26.csv @@ -111,6 +111,7 @@ compare cstdint compare limits compare version complex cmath +complex cstddef complex sstream complex version concepts cstddef diff --git a/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp b/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp new file mode 100644 index 0000000..b1d1998 --- /dev/null +++ b/libcxx/test/libcxx/utilities/tuple/__tuple_like.compile.pass.cpp @@ -0,0 +1,93 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// <tuple> + +// 22.4.3 Concept `tuple-like` [tuple.like] +// +// template<class T> +// concept tuple-like; // exposition only + +#include <array> +#include <complex> +#include <ranges> +#include <tuple> + +#include "test_iterators.h" + +// Non-tuple-like type + +static_assert(!std::__tuple_like<int>); + +// Tuple-like: array + +static_assert(std::__tuple_like<std::array<int, 0>>); +static_assert(std::__tuple_like<std::array<int, 1>>); +static_assert(std::__tuple_like<std::array<int, 2>>); +static_assert(std::__tuple_like<std::array<int, 2728>>); + +// Tuple-like: complex + +#if _LIBCPP_STD_VER >= 26 +static_assert(std::__tuple_like<std::complex<float>>); +static_assert(std::__tuple_like<std::complex<double>>); +static_assert(std::__tuple_like<std::complex<long double>>); +#endif + +// Tuple-like: pair + +static_assert(std::__tuple_like<std::pair<int, float>>); + +// Tuple-like: tuple + +static_assert(std::__tuple_like<std::tuple<int>>); +static_assert(std::__tuple_like<std::tuple<int, float>>); +static_assert(std::__tuple_like<std::tuple<int, float, double>>); + +// Support for <ranges> + +using FI = forward_iterator<int*>; +static_assert(std::__tuple_like<std::ranges::subrange<FI, FI, std::ranges::subrange_kind::sized>>); +static_assert(std::__tuple_like<std::ranges::subrange<FI, FI, std::ranges::subrange_kind::unsized>>); +static_assert(std::__tuple_like<std::ranges::subrange<int*, int*, std::ranges::subrange_kind::sized>>); +static_assert(std::__tuple_like<std::ranges::subrange<int*, std::nullptr_t, std::ranges::subrange_kind::unsized>>); + +template <typename Iter> +void test_subrange_sized() { + static_assert(std::__tuple_like<std::ranges::subrange<Iter, Iter, std::ranges::subrange_kind::sized>>); +} + +template <typename Iter> +void test_subrange_unsized() { + static_assert(std::__tuple_like<std::ranges::subrange<Iter, Iter, std::ranges::subrange_kind::unsized>>); +} + +void test() { + test_subrange_sized<forward_iterator<int*>>(); + test_subrange_sized<bidirectional_iterator<int*>>(); + test_subrange_sized<random_access_iterator<int*>>(); + test_subrange_sized<contiguous_iterator<int*>>(); + test_subrange_sized<int*>(); + + test_subrange_sized<forward_iterator<int const*>>(); + test_subrange_sized<bidirectional_iterator<int const*>>(); + test_subrange_sized<random_access_iterator<int const*>>(); + test_subrange_sized<contiguous_iterator<int const*>>(); + test_subrange_sized<int const*>(); + + test_subrange_unsized<forward_iterator<int*>>(); + test_subrange_unsized<bidirectional_iterator<int*>>(); + static_assert(std::__tuple_like<std::ranges::subrange<int*, std::nullptr_t, std::ranges::subrange_kind::unsized>>); + + test_subrange_unsized<forward_iterator<int const*>>(); + test_subrange_unsized<bidirectional_iterator<int const*>>(); + static_assert( + std::__tuple_like<std::ranges::subrange<const int*, std::nullptr_t, std::ranges::subrange_kind::unsized>>); +} diff --git a/libcxx/test/std/numerics/complex.number/complex.tuple/get.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.tuple/get.pass.cpp new file mode 100644 index 0000000..bd514a6 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.tuple/get.pass.cpp @@ -0,0 +1,133 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// <complex> + +// template<size_t I, class T> +// constexpr T& get(complex<T>&) noexcept; +// template<size_t I, class T> +// constexpr T&& get(complex<T>&&) noexcept; +// template<size_t I, class T> +// constexpr const T& get(const complex<T>&) noexcept; +// template<size_t I, class T> +// constexpr const T&& get(const complex<T>&&) noexcept; + +#include <cassert> +#include <complex> +#include <concepts> +#include <ranges> +#include <vector> +#include <utility> + +template <typename T> +constexpr void test() { + // & + { + std::complex<T> c{T{27}, T{28}}; + + std::same_as<T&> decltype(auto) r = get<0>(c); + static_assert(noexcept(get<0>(c))); + assert(r == T{27}); + std::same_as<T&> decltype(auto) i = get<1>(c); + static_assert(noexcept(get<1>(c))); + assert(i == T{28}); + } + // && + { + std::complex<T> c{T{27}, T{28}}; + + std::same_as<T&&> decltype(auto) r = get<0>(std::move(c)); + static_assert(noexcept(get<0>(c))); + assert(r == T{27}); + } + { + std::complex<T> c{T{27}, T{28}}; + + std::same_as<T&&> decltype(auto) i = get<1>(std::move(c)); + static_assert(noexcept(get<1>(c))); + assert(i == T{28}); + } + // const & + { + const std::complex<T> c{T{27}, T{28}}; + + std::same_as<const T&> decltype(auto) r = get<0>(c); + static_assert(noexcept(get<0>(c))); + assert(r == T{27}); + std::same_as<const T&> decltype(auto) i = get<1>(c); + static_assert(noexcept(get<1>(c))); + assert(i == T{28}); + } + // const && + { + const std::complex<T> c{T{27}, T{28}}; + + std::same_as<const T&&> decltype(auto) r = get<0>(std::move(c)); + static_assert(noexcept(get<0>(c))); + assert(r == T{27}); + } + { + const std::complex<T> c{T{27}, T{28}}; + + std::same_as<const T&&> decltype(auto) i = get<1>(std::move(c)); + static_assert(noexcept(get<1>(c))); + assert(i == T{28}); + } + // `get()` allows using `complex` with structured bindings + { + std::complex<T> c{T{27}, T{28}}; + + auto [r, i]{c}; + static_assert(std::same_as<T, decltype(r)>); + assert(r == T{27}); + static_assert(std::same_as<T, decltype(i)>); + assert(i == T{28}); + } + { + std::complex<T> c{T{27}, T{28}}; + + auto& [r, i]{c}; + static_assert(std::same_as<T, decltype(r)>); + assert(r == T{27}); + static_assert(std::same_as<T, decltype(i)>); + assert(i == T{28}); + } + // `get()` allows using `complex` with ranges + { + std::complex<T> arr[]{{T{27}, T{28}}, {T{82}, T{94}}}; + + std::same_as<std::vector<T>> decltype(auto) reals{ + arr | std::views::elements<0> | std::ranges::to<std::vector<T>>()}; + assert(reals.size() == 2); + assert(reals[0] == T{27}); + assert(reals[1] == T{82}); + + std::same_as<std::vector<T>> decltype(auto) imags{ + arr | std::views::elements<1> | std::ranges::to<std::vector<T>>()}; + assert(reals.size() == 2); + assert(imags[0] == T{28}); + assert(imags[1] == T{94}); + } +} + +constexpr bool test() { + test<float>(); + test<double>(); + test<long double>(); + + return true; +} + +int main(int, char**) { + test(); + static_assert(test()); + + return 0; +} diff --git a/libcxx/test/std/numerics/complex.number/complex.tuple/get.verify.cpp b/libcxx/test/std/numerics/complex.number/complex.tuple/get.verify.cpp new file mode 100644 index 0000000..6a6e3a9 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.tuple/get.verify.cpp @@ -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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// <complex> + +// template<size_t I, class T> +// constexpr T& get(complex<T>&) noexcept; +// template<size_t I, class T> +// constexpr T&& get(complex<T>&&) noexcept; +// template<size_t I, class T> +// constexpr const T& get(const complex<T>&) noexcept; +// template<size_t I, class T> +// constexpr const T&& get(const complex<T>&&) noexcept; + +#include <cassert> +#include <complex> +#include <utility> + +template <typename T> +void test() { + using C = std::complex<T>; + + // & + { + C c{T{27}, T{28}}; + // expected-error-re@*:* 3{{static assertion failed {{.*}}Index value is out of range.}} + std::get<3>(c); + } + // && + { + C c{T{27}, T{28}}; + // expected-error-re@*:* 3 {{static assertion failed {{.*}}Index value is out of range.}} + std::get<3>(std::move(c)); + } + // const & + { + const C c{T{27}, T{28}}; + // expected-error-re@*:* 3 {{static assertion failed {{.*}}Index value is out of range.}} + std::get<3>(c); + } + // const && + { + const C c{T{27}, T{28}}; + // expected-error-re@*:* 3 {{static assertion failed {{.*}}Index value is out of range.}} + std::get<3>(std::move(c)); + } +} + +void test() { + test<float>(); + test<double>(); + test<long double>(); +} diff --git a/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_element.compile.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_element.compile.pass.cpp new file mode 100644 index 0000000..50c0e0e --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_element.compile.pass.cpp @@ -0,0 +1,43 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// <complex> + +// template<size_t I, class T> struct tuple_element; + +#include <cassert> +#include <complex> +#include <concepts> + +template <size_t I, typename C> +concept HasTupleElement = requires { std::tuple_element<I, C>{}; }; + +struct SomeObject {}; + +static_assert(!HasTupleElement<0, SomeObject>); +static_assert(!HasTupleElement<1, SomeObject>); +static_assert(!HasTupleElement<3, SomeObject>); + +template <typename T> +void test() { + using C = std::complex<T>; + + static_assert(HasTupleElement<0, C>); + static_assert(HasTupleElement<1, C>); + + static_assert(std::same_as<typename std::tuple_element<0, C>::type, T>); + static_assert(std::same_as<typename std::tuple_element<1, C>::type, T>); +} + +void test() { + test<float>(); + test<double>(); + test<long double>(); +} diff --git a/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_element.verify.cpp b/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_element.verify.cpp new file mode 100644 index 0000000..879e215 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_element.verify.cpp @@ -0,0 +1,31 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// <complex> + +// template<size_t I, class T> struct tuple_element; + +#include <cassert> +#include <complex> +#include <concepts> + +template <typename T> +void test() { + using C = std::complex<T>; + + // expected-error-re@*:* 3 {{static assertion failed {{.*}}Index value is out of range.}} + [[maybe_unused]] std::tuple_element<3, C> te{}; +} + +void test() { + test<float>(); + test<double>(); + test<long double>(); +} diff --git a/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_size.compile.pass.cpp b/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_size.compile.pass.cpp new file mode 100644 index 0000000..28dcbe3 --- /dev/null +++ b/libcxx/test/std/numerics/complex.number/complex.tuple/tuple_size.compile.pass.cpp @@ -0,0 +1,39 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20, c++23 + +// <complex> + +// template<class T> struct tuple_size; + +#include <cassert> +#include <complex> +#include <concepts> + +template <typename C> +concept HasTupleSize = requires { std::tuple_size<C>{}; }; + +struct SomeObject {}; + +static_assert(!HasTupleSize<SomeObject>); + +template <typename T> +void test() { + using C = std::complex<T>; + + static_assert(HasTupleSize<C>); + static_assert(std::same_as<typename std::tuple_size<C>::value_type, size_t>); + static_assert(std::tuple_size<C>() == 2); +} + +void test() { + test<float>(); + test<double>(); + test<long double>(); +} diff --git a/libcxx/utils/generate_feature_test_macro_components.py b/libcxx/utils/generate_feature_test_macro_components.py index 9e7ea86..b688a30 100755 --- a/libcxx/utils/generate_feature_test_macro_components.py +++ b/libcxx/utils/generate_feature_test_macro_components.py @@ -1228,7 +1228,7 @@ feature_test_macros = [ "name": "__cpp_lib_tuple_like", "values": { "c++23": 202207, # P2165R4 Compatibility between tuple, pair and tuple-like objects - "c++26": 202311, # P2819R2 Add tuple protocol to complex + "c++26": 202311, # P2819R2 Add tuple protocol to complex (implemented) }, "headers": ["map", "tuple", "unordered_map", "utility"], "unimplemented": True, |