public inbox for libstdc++@gcc.gnu.org
 help / color / mirror / Atom feed
* [PATCH v2 0/2] libstdc++: generators v2
@ 2023-12-21 20:01 Arsen Arsenović
  2023-12-21 20:01 ` [PATCH v2 1/2] libstdc++: add missing include in ranges_util.h Arsen Arsenović
  2023-12-21 20:01 ` [PATCH v2 2/2] libstdc++: implement std::generator Arsen Arsenović
  0 siblings, 2 replies; 10+ messages in thread
From: Arsen Arsenović @ 2023-12-21 20:01 UTC (permalink / raw)
  To: gcc-patches; +Cc: libstdc++, Arsen Arsenović

Hi,

This is v2 of my generators patch.  It addresses Jonathans review
comments, but does not add more tests yet :-/

Original series:
https://inbox.sourceware.org/20231118195008.579211-1-arsen@aarsen.me/

Changes since v1:
- Uglify some symbols
- Convert _Is_generator concept to __is_generator CE bool
- Add "libstdc++: add missing include in ranges_util.h" - this can be
  pushed separately, really, but I forgot to send it.

Range-diff:

1:  feab374887e5 = 1212:  c4286af0c70f libstdc++: add missing include in ranges_util.h
2:  010eab271755 ! 1213:  fb589641656f libstdc++: implement std::generator
 @@ libstdc++-v3/include/std/generator (new)
  +#define __glibcxx_want_generator
  +#include <bits/version.h>
  +
 -+#if __cplusplus < 202302L
 -+# error "std::generator is a C++23 extension"
 -+#endif
 -+
  +#ifdef __cpp_lib_generator  // C++ >= 23 && __glibcxx_coroutine
  +#include <new>
  +#include <bits/move.h>
 @@ libstdc++-v3/include/std/generator (new)
  +  {
  +    /// _Reference type for a generator whose reference (first argument) and
  +    /// value (second argument) types are _Ref and _V.
 -+    template<typename _Ref, typename _V>
 -+    using _Reference_t = __conditional_t<is_void_v<_V>,
 ++    template<typename _Ref, typename _Val>
 ++    using _Reference_t = __conditional_t<is_void_v<_Val>,
  +					_Ref&&, _Ref>;
  +
  +    /// Type yielded by a generator whose _Reference type is _Reference.
 @@ libstdc++-v3/include/std/generator (new)
  +				    const _Reference&>;
  +
  +    /// _Yield_t * _Reference_t
 -+    template<typename _Ref, typename _V>
 -+    using _Yield2_t = _Yield_t<_Reference_t<_Ref, _V>>;
 -+
 -+    template<typename> struct _Is_generator_t : std::false_type {};
 -+    template<typename _V, typename _R, typename _A>
 -+      struct _Is_generator_t<::std::generator<_V, _R, _A>> : std::true_type {};
 -+
 -+    template<typename _T>
 -+    concept _Is_generator = _Is_generator_t<remove_cvref_t<_T>>::value;
 ++    template<typename _Ref, typename _Val>
 ++    using _Yield2_t = _Yield_t<_Reference_t<_Ref, _Val>>;
  +
 ++    template<typename> constexpr bool __is_generator = false;
 ++    template<typename _Val, typename _Ref, typename _Alloc>
 ++    constexpr bool __is_generator<std::generator<_Val, _Ref, _Alloc>> = true;
  +
  +    /// Allocator and value type erased generator promise type.
  +    /// \tparam _Yielded The corresponding generators yielded type.
 @@ libstdc++-v3/include/std/generator (new)
  +	using _Coro_handle = std::coroutine_handle<_Promise_erased>;
  +
  +	template<typename, typename, typename>
 -+	friend struct std::generator;
 ++	friend class std::generator;
  +
  +	template<typename _Gen>
  +	 struct _Recursive_awaiter;
 @@ libstdc++-v3/include/std/generator (new)
  +	 __rn._M_top() = __new;
  +
  +	 // Presume we're the second frame...
 -+	 auto& __bott = __rest;
 ++	 auto __bott = __rest;
  +	 if (auto __f = std::get_if<_Frame>(&__rn._M_stack))
  +	   // But, if we aren't, get the actual bottom.  We're only the second
  +	   // frame if our parent is the bottom frame, i.e. it doesn't have a
 @@ libstdc++-v3/include/std/generator (new)
  +      struct _Promise_erased<_Yielded>::_Recursive_awaiter
  +      {
  +	_Gen _M_gen;
 -+	static_assert(_Is_generator<_Gen>);
 ++	static_assert(__is_generator<_Gen>);
  +	static_assert(std::same_as<typename _Gen::yielded, _Yielded>);
  +
  +	_Recursive_awaiter(_Gen __gen) noexcept
 @@ libstdc++-v3/include/std/generator (new)
  +	 requires default_initializable<_Rebound> // _Alloc is non-void
  +	{ return _M_allocate({}, __sz); }
  +
 -+	template<typename _NA, typename... _Args>
 ++	template<typename _Na, typename... _Args>
  +	void*
  +	operator new(std::size_t __sz,
 -+		    allocator_arg_t, const _NA& __na,
 ++		    allocator_arg_t, const _Na& __na,
  +		    const _Args&...)
 -+	 requires convertible_to<const _NA&, _Alloc>
 ++	 requires convertible_to<const _Na&, _Alloc>
  +	{
  +	 return _M_allocate(static_cast<_Rebound>(static_cast<_Alloc>(__na)),
  +			    __sz);
  +	}
  +
 -+	template<typename _This, typename _NA, typename... _Args>
 ++	template<typename _This, typename _Na, typename... _Args>
  +	void*
  +	operator new(std::size_t __sz,
  +		    const _This&,
 -+		    allocator_arg_t, const _NA& __na,
 ++		    allocator_arg_t, const _Na& __na,
  +		    const _Args&...)
 -+	 requires convertible_to<const _NA&, _Alloc>
 ++	 requires convertible_to<const _Na&, _Alloc>
  +	{
  +	 return _M_allocate(static_cast<_Rebound>(static_cast<_Alloc>(__na)),
  +			    __sz);
 @@ libstdc++-v3/include/std/generator (new)
  +	   }
  +	}
  +
 -+	template<typename _NA>
 ++	template<typename _Na>
  +	static void*
 -+	_M_allocate(const _NA& __na, std::size_t __csz)
 ++	_M_allocate(const _Na& __na, std::size_t __csz)
  +	{
 -+	 using _Rebound = typename std::allocator_traits<_NA>
 ++	 using _Rebound = typename std::allocator_traits<_Na>
  +	   ::template rebind_alloc<_Alloc_block>;
 -+	 using _Rebound_ATr = typename std::allocator_traits<_NA>
 ++	 using _Rebound_ATr = typename std::allocator_traits<_Na>
  +	   ::template rebind_traits<_Alloc_block>;
  +
  +	 static_assert(is_pointer_v<typename _Rebound_ATr::pointer>,
 @@ libstdc++-v3/include/std/generator (new)
  +	 return __p;
  +	}
  +
 -+	template<typename _NA, typename... _Args>
 ++	template<typename _Na, typename... _Args>
  +	void*
  +	operator new(std::size_t __sz,
 -+		    allocator_arg_t, const _NA& __na,
 ++		    allocator_arg_t, const _Na& __na,
  +		    const _Args&...)
  +	{ return _M_allocate(__na, __sz); }
  +
 -+	template<typename _This, typename _NA, typename... _Args>
 ++	template<typename _This, typename _Na, typename... _Args>
  +	void*
  +	operator new(std::size_t __sz,
  +		    const _This&,
 -+		    allocator_arg_t, const _NA& __na,
 ++		    allocator_arg_t, const _Na& __na,
  +		    const _Args&...)
  +	{ return _M_allocate(__na, __sz); }
  +
 @@ libstdc++-v3/include/std/generator (new)
  +	}
  +      };
  +
 -+    template<typename _T>
 -+    concept _Cv_unqualified_object = is_object_v<_T>
 -+      && same_as<_T, remove_cv_t<_T>>;
 ++    template<typename _Tp>
 ++    concept _Cv_unqualified_object = is_object_v<_Tp>
 ++      && same_as<_Tp, remove_cv_t<_Tp>>;
  +  } // namespace __gen
  +  /// @endcond
  +
 @@ libstdc++-v3/include/std/generator (new)
  +      using difference_type = ptrdiff_t;
  +
  +      friend bool
 -+      operator==(const _Iterator& i, default_sentinel_t) noexcept
 -+      { return i._M_coro.done(); }
 ++      operator==(const _Iterator& __i, default_sentinel_t) noexcept
 ++      { return __i._M_coro.done(); }
  +
  +      friend class generator;
  +
 @@ libstdc++-v3/include/std/generator (new)
  +
  +#if _GLIBCXX_HOSTED
  +  namespace pmr {
 -+    template<class R, class V = void>
 -+    using generator = std::generator<R, V, polymorphic_allocator<std::byte>>;
 ++    template<typename _Ref, typename _Val = void>
 ++    using generator = std::generator<_Ref, _Val, polymorphic_allocator<std::byte>>;
  +  }
  +#endif // HOSTED
  +

Tested libstdc++ on x86_64-pc-linux-gnu.

TIA, have a lovely day.

Arsen Arsenović (2):
  libstdc++: add missing include in ranges_util.h
  libstdc++: implement std::generator

 libstdc++-v3/include/Makefile.am              |   2 +
 libstdc++-v3/include/Makefile.in              |   2 +
 libstdc++-v3/include/bits/elements_of.h       |  72 ++
 libstdc++-v3/include/bits/ranges_util.h       |   1 +
 libstdc++-v3/include/bits/version.def         |   9 +
 libstdc++-v3/include/bits/version.h           |  11 +
 libstdc++-v3/include/precompiled/stdc++.h     |   1 +
 libstdc++-v3/include/std/generator            | 812 ++++++++++++++++++
 libstdc++-v3/include/std/ranges               |   4 +
 .../24_iterators/range_generators/01.cc       |  55 ++
 .../24_iterators/range_generators/02.cc       | 219 +++++
 .../24_iterators/range_generators/copy.cc     |  97 +++
 .../24_iterators/range_generators/except.cc   |  97 +++
 .../24_iterators/range_generators/subrange.cc |  45 +
 .../24_iterators/range_generators/synopsis.cc |  38 +
 15 files changed, 1465 insertions(+)
 create mode 100644 libstdc++-v3/include/bits/elements_of.h
 create mode 100644 libstdc++-v3/include/std/generator
 create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/01.cc
 create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/02.cc
 create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/copy.cc
 create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/except.cc
 create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/subrange.cc
 create mode 100644 libstdc++-v3/testsuite/24_iterators/range_generators/synopsis.cc

-- 
2.43.0


^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2024-01-04 12:57 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-21 20:01 [PATCH v2 0/2] libstdc++: generators v2 Arsen Arsenović
2023-12-21 20:01 ` [PATCH v2 1/2] libstdc++: add missing include in ranges_util.h Arsen Arsenović
2023-12-21 21:37   ` Jonathan Wakely
2023-12-21 20:01 ` [PATCH v2 2/2] libstdc++: implement std::generator Arsen Arsenović
2023-12-21 21:51   ` Jonathan Wakely
2023-12-26 20:28   ` Will Hawkins
2023-12-26 23:04     ` Arsen Arsenović
2024-01-04 10:30   ` Jonathan Wakely
2024-01-04 12:00     ` Arsen Arsenović
2024-01-04 12:57       ` Jonathan Wakely

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).