From 83bc2c27ab0ce4b2ad7c4b15009e47cbbf4a5e95 Mon Sep 17 00:00:00 2001 From: Cra3z <3324654761@qq.com> Date: Sun, 11 Jan 2026 12:38:40 +0800 Subject: [PATCH 1/5] implement allocator concept --- include/stdexec/__detail/__concepts.hpp | 10 ++++++++++ include/stdexec/__detail/__queries.hpp | 6 +----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/stdexec/__detail/__concepts.hpp b/include/stdexec/__detail/__concepts.hpp index bf4504787..fb31e1c4e 100644 --- a/include/stdexec/__detail/__concepts.hpp +++ b/include/stdexec/__detail/__concepts.hpp @@ -271,4 +271,14 @@ namespace stdexec { template requires __none_of<_Ty, _Us...> using __unless_one_of_t = _Ty; + + template + concept __allocator = + requires(std::remove_cvref_t<_Alloc> __al, std::size_t __n) { + { + __al.allocate(__n) + } -> std::same_as::value_type>>; + __al.deallocate(__al.allocate(__n), __n); + } && std::copy_constructible> + && std::equality_comparable>; } // namespace stdexec diff --git a/include/stdexec/__detail/__queries.hpp b/include/stdexec/__detail/__queries.hpp index 6fcf67240..196e222e7 100644 --- a/include/stdexec/__detail/__queries.hpp +++ b/include/stdexec/__detail/__queries.hpp @@ -27,10 +27,6 @@ namespace stdexec { ////////////////////////////////////////////////////////////////////////////////////////////////// // [exec.queries] namespace __queries { - // TODO: implement allocator concept - template - concept __allocator_c = true; - ////////////////////////////////////////////////////////////////////////////////// // [exec.get.allocator] struct get_allocator_t : __query { @@ -44,7 +40,7 @@ namespace stdexec { STDEXEC_ATTRIBUTE(always_inline, host, device) static constexpr void __validate() noexcept { static_assert(__nothrow_callable); - static_assert(__allocator_c<__call_result_t>); + static_assert(__allocator<__call_result_t>); } STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device) From c27823ae74bf7eeb9db05645c9e5a4101702bb87 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sun, 11 Jan 2026 14:06:10 -0800 Subject: [PATCH 2/5] use the `stdexec::` versions of the concepts --- include/stdexec/__detail/__concepts.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/stdexec/__detail/__concepts.hpp b/include/stdexec/__detail/__concepts.hpp index fb31e1c4e..7f11f0f62 100644 --- a/include/stdexec/__detail/__concepts.hpp +++ b/include/stdexec/__detail/__concepts.hpp @@ -277,8 +277,8 @@ namespace stdexec { requires(std::remove_cvref_t<_Alloc> __al, std::size_t __n) { { __al.allocate(__n) - } -> std::same_as::value_type>>; + } -> same_as::value_type>>; __al.deallocate(__al.allocate(__n), __n); - } && std::copy_constructible> - && std::equality_comparable>; + } && copy_constructible> + && equality_comparable>; } // namespace stdexec From 8d09a4704bdaa58b6fe0ab9ea26fcc9125d00c9e Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Sun, 11 Jan 2026 14:54:22 -0800 Subject: [PATCH 3/5] fix `allocate` constraint in `__allocator` concept, clang-format --- include/stdexec/__detail/__concepts.hpp | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/include/stdexec/__detail/__concepts.hpp b/include/stdexec/__detail/__concepts.hpp index 7f11f0f62..f8e923208 100644 --- a/include/stdexec/__detail/__concepts.hpp +++ b/include/stdexec/__detail/__concepts.hpp @@ -272,13 +272,22 @@ namespace stdexec { requires __none_of<_Ty, _Us...> using __unless_one_of_t = _Ty; + namespace __detail { + template + auto __test_alloc_pointer(int) -> typename _Alloc::pointer; + template + auto __test_alloc_pointer(long) -> typename _Alloc::value_type*; + + template + using __alloc_pointer_t = decltype(__detail::__test_alloc_pointer<__decay_t<_Alloc>>(0)); + } // namespace __detail + template - concept __allocator = - requires(std::remove_cvref_t<_Alloc> __al, std::size_t __n) { - { - __al.allocate(__n) - } -> same_as::value_type>>; - __al.deallocate(__al.allocate(__n), __n); - } && copy_constructible> - && equality_comparable>; + concept __allocator = // + requires(__declfn_t<__decay_t<_Alloc>&> __al, std::size_t __n) { + { __al().allocate(__n) } -> same_as<__detail::__alloc_pointer_t<_Alloc>>; + __al().deallocate(__al().allocate(__n), __n); + } // + && copy_constructible<__decay_t<_Alloc>> // + && equality_comparable<__decay_t<_Alloc>>; } // namespace stdexec From cd5fb3b7192434949658e31ef066574f70dec576 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 12 Jan 2026 08:21:10 -0800 Subject: [PATCH 4/5] trying to molify msvc --- include/stdexec/__detail/__concepts.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/stdexec/__detail/__concepts.hpp b/include/stdexec/__detail/__concepts.hpp index f8e923208..7094eb7e4 100644 --- a/include/stdexec/__detail/__concepts.hpp +++ b/include/stdexec/__detail/__concepts.hpp @@ -284,9 +284,9 @@ namespace stdexec { template concept __allocator = // - requires(__declfn_t<__decay_t<_Alloc>&> __al, std::size_t __n) { - { __al().allocate(__n) } -> same_as<__detail::__alloc_pointer_t<_Alloc>>; - __al().deallocate(__al().allocate(__n), __n); + requires(__decay_t<_Alloc>& __alloc, std::size_t __bytes) { + { __alloc.allocate(__bytes) } -> same_as<__detail::__alloc_pointer_t<_Alloc>>; + __alloc.deallocate(__alloc.allocate(__bytes), __bytes); } // && copy_constructible<__decay_t<_Alloc>> // && equality_comparable<__decay_t<_Alloc>>; From 4a5002abdc337b6826bc11b4397cf86d0ea1c18c Mon Sep 17 00:00:00 2001 From: Cra3z <3324654761@qq.com> Date: Tue, 13 Jan 2026 22:30:34 +0800 Subject: [PATCH 5/5] rename `__allocator` to `__allocator_` --- include/stdexec/__detail/__concepts.hpp | 2 +- include/stdexec/__detail/__queries.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/stdexec/__detail/__concepts.hpp b/include/stdexec/__detail/__concepts.hpp index 7094eb7e4..54d00728a 100644 --- a/include/stdexec/__detail/__concepts.hpp +++ b/include/stdexec/__detail/__concepts.hpp @@ -283,7 +283,7 @@ namespace stdexec { } // namespace __detail template - concept __allocator = // + concept __allocator_ = // requires(__decay_t<_Alloc>& __alloc, std::size_t __bytes) { { __alloc.allocate(__bytes) } -> same_as<__detail::__alloc_pointer_t<_Alloc>>; __alloc.deallocate(__alloc.allocate(__bytes), __bytes); diff --git a/include/stdexec/__detail/__queries.hpp b/include/stdexec/__detail/__queries.hpp index 196e222e7..6a8c74530 100644 --- a/include/stdexec/__detail/__queries.hpp +++ b/include/stdexec/__detail/__queries.hpp @@ -40,7 +40,7 @@ namespace stdexec { STDEXEC_ATTRIBUTE(always_inline, host, device) static constexpr void __validate() noexcept { static_assert(__nothrow_callable); - static_assert(__allocator<__call_result_t>); + static_assert(__allocator_<__call_result_t>); } STDEXEC_ATTRIBUTE(nodiscard, always_inline, host, device)