From a4e6cf115d1ed93d3e8cb15bb7e84dd9986d4224 Mon Sep 17 00:00:00 2001 From: Ian Petersen Date: Thu, 23 Jul 2026 14:03:27 -0700 Subject: [PATCH 1/4] Bootstrap a broken modules build This diff doesn't build, but it doesn't build for a good reason: it's successfully invoking the "build with modules" machinery, which is exposing implementation gaps. It looks like the next step is to start updating `stdexec` headers that include std headers to conditionally rely on `import std` instead, at least when `STDEXEC_IN_MODULE_PURVIEW` is defined. --- CMakeLists.txt | 57 +++++++++++++++++----- cmake/enable-experimental-import-std.cmake | 24 +++++++++ include/stdexec/__detail/__config.hpp | 7 +++ modules/stdexec.cppm | 17 +++++++ test/CMakeLists.txt | 14 +++++- test/stdexec/module/test_module.cpp | 30 ++++++++++++ 6 files changed, 136 insertions(+), 13 deletions(-) create mode 100644 cmake/enable-experimental-import-std.cmake create mode 100644 modules/stdexec.cppm create mode 100644 test/stdexec/module/test_module.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 51afa9d63..5559dfcba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.25.0) +cmake_minimum_required(VERSION 3.28.0) set(ENV{SCCACHE_NO_DIST_COMPILE} "1") @@ -23,6 +23,8 @@ if(POLICY CMP0167) set(CMAKE_POLICY_DEFAULT_CMP0167 NEW) endif() +include(cmake/enable-experimental-import-std.cmake) + ############################################################################## # Initialize rapids-cmake include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/RAPIDS.cmake) @@ -172,7 +174,20 @@ option(STDEXEC_BUILD_RELACY_TESTS "Build stdexec relacy tests" ${STDEXEC_BUILD_R set(stdexec_export_targets) # Define the main library -add_library(stdexec INTERFACE) +option(STDEXEC_BUILD_MODULES "Build stdexec C++20 modules" OFF) +if(STDEXEC_BUILD_MODULES) + set(stdexec_scope PUBLIC) + set(CMAKE_CXX_SCAN_FOR_MODULES ON) +else() + set(stdexec_scope INTERFACE) +endif() + +if(STDEXEC_BUILD_MODULES) + add_library(stdexec OBJECT) + target_compile_definitions(stdexec PUBLIC STDEXEC_BUILD_MODULES=1) +else() + add_library(stdexec INTERFACE) +endif() file(GLOB_RECURSE exec_headers CONFIGURE_DEPENDS include/exec/*.hpp) file(GLOB_RECURSE stdexec_headers CONFIGURE_DEPENDS include/stdexec/*.hpp) @@ -191,8 +206,21 @@ PUBLIC FILES ${CMAKE_CURRENT_BINARY_DIR}/include/stdexec_version_config.hpp ) +if(STDEXEC_BUILD_MODULES) + target_sources(stdexec + PUBLIC + FILE_SET CXX_MODULES + TYPE CXX_MODULES + BASE_DIRS modules + FILES + modules/stdexec.cppm + ) + + set_target_properties(stdexec PROPERTIES CXX_MODULE_STD ON) +endif() + # Mark include directories as SYSTEM so consumers don't get warnings from stdexec internals -target_include_directories(stdexec SYSTEM INTERFACE +target_include_directories(stdexec SYSTEM ${stdexec_scope} $ $ $ @@ -214,10 +242,16 @@ endif() # Declare the public include directories include(GNUInstallDirs) -target_link_libraries(stdexec INTERFACE Threads::Threads) +target_link_libraries(stdexec ${stdexec_scope} Threads::Threads) -# Use C++20 standard -target_compile_features(stdexec INTERFACE cxx_std_20) +if(STDEXEC_BUILD_MODULES) + # Use C++23 standard; modules were introduced in 20 so this feels + # like it ought to be unnecessary, but it makes `import std` work + target_compile_features(stdexec ${stdexec_scope} cxx_std_23) +else() + # Use C++20 standard + target_compile_features(stdexec ${stdexec_scope} cxx_std_20) +endif() # # Enable GPU compilation when using NVHPC compiler # target_compile_options(stdexec INTERFACE @@ -228,28 +262,28 @@ target_compile_features(stdexec INTERFACE cxx_std_20) # ) # Enable coroutines for GCC -target_compile_options(stdexec INTERFACE +target_compile_options(stdexec ${stdexec_scope} $<$:-fcoroutines> ) # Increase the concepts diagnostics depth for GCC -target_compile_options(stdexec INTERFACE +target_compile_options(stdexec ${stdexec_scope} $<$:-fconcepts-diagnostics-depth=10> ) # Do you want a preprocessor that works? Picky, picky. -target_compile_options(stdexec INTERFACE +target_compile_options(stdexec ${stdexec_scope} $<$:/Zc:__cplusplus /Zc:preprocessor /Zc:externConstexpr /bigobj> ) set(STDEXEC_NAMESPACE "stdexec" CACHE STRING "The name of the top-level namespace for stdexec") if (NOT STDEXEC_NAMESPACE STREQUAL "stdexec") - target_compile_definitions(stdexec INTERFACE STDEXEC_NAMESPACE=${STDEXEC_NAMESPACE}) + target_compile_definitions(stdexec ${stdexec_scope} STDEXEC_NAMESPACE=${STDEXEC_NAMESPACE}) endif() option(STDEXEC_ENABLE_EXTRA_TYPE_CHECKING "Enable extra type checking that is costly at compile-time" OFF) if (STDEXEC_ENABLE_EXTRA_TYPE_CHECKING) - target_compile_definitions(stdexec INTERFACE STDEXEC_ENABLE_EXTRA_TYPE_CHECKING) + target_compile_definitions(stdexec ${stdexec_scope} STDEXEC_ENABLE_EXTRA_TYPE_CHECKING) endif() add_library(STDEXEC::stdexec ALIAS stdexec) @@ -519,6 +553,7 @@ endif() ############################################################################## # Install targets ------------------------------------------------------------ +# TODO: this is broken in the modules build if(STDEXEC_INSTALL) include(CPack) diff --git a/cmake/enable-experimental-import-std.cmake b/cmake/enable-experimental-import-std.cmake new file mode 100644 index 000000000..e41a5f7c4 --- /dev/null +++ b/cmake/enable-experimental-import-std.cmake @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +if(CMAKE_VERSION VERSION_GREATER_EQUAL "4.3.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "451f2fe2-a8a2-47c3-bc32-94786d8fc91b" + ) +elseif(CMAKE_VERSION VERSION_GREATER_EQUAL "3.30.0") + if(CMAKE_VERSION VERSION_LESS "3.31.8") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "0e5b6991-d74f-4b3d-a41c-cf096e0b2508" + ) + elseif(CMAKE_VERSION VERSION_LESS "4.0.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) + elseif(CMAKE_VERSION VERSION_LESS "4.0.3") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "a9e1cf81-9932-4810-974b-6eccaf14e457" + ) + elseif(CMAKE_VERSION VERSION_LESS "4.3.0") + set(CMAKE_EXPERIMENTAL_CXX_IMPORT_STD + "d0edc3af-4c50-42ea-a356-e2862fe7a444" + ) + endif() +endif() diff --git a/include/stdexec/__detail/__config.hpp b/include/stdexec/__detail/__config.hpp index aa7b1125b..3d8f1aae4 100644 --- a/include/stdexec/__detail/__config.hpp +++ b/include/stdexec/__detail/__config.hpp @@ -29,6 +29,13 @@ # error This library requires the use of the new conforming preprocessor enabled by /Zc:preprocessor. #endif +#if defined(STDEXEC_BUILD_MODULES) +# define STDEXEC_USE_MODULES() 1 +# undef STDEXEC_BUILD_MODULES +#else +# define STDEXEC_USE_MODULES() 0 +#endif + #include "__preprocessor.hpp" #if __has_include() diff --git a/modules/stdexec.cppm b/modules/stdexec.cppm new file mode 100644 index 000000000..30ad92808 --- /dev/null +++ b/modules/stdexec.cppm @@ -0,0 +1,17 @@ +module; + +#include + +export module stdexec; + +import std; + +#define STDEXEC_IN_MODULE_PURVIEW +#define STDEXEC_MODULE_EXPORT export + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Winclude-angled-in-module-purview" + +#include + +#pragma clang diagnostic pop diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index e14a0469d..5c05bedfa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -109,7 +109,14 @@ target_link_libraries(common_test_settings INTERFACE $,$>>:STDEXEC_ENABLE_EXTRA_TYPE_CHECKING>) -add_executable(test.stdexec ${stdexec_test_sources}) +if(STDEXEC_BUILD_MODULES) + # temporarily speed up the test cycle by building only one test + add_executable(test.stdexec stdexec/module/test_module.cpp) + set_target_properties(test.stdexec PROPERTIES CXX_MODULE_STD ON) +else() + add_executable(test.stdexec ${stdexec_test_sources}) +endif() + add_compile_diagnostics(test.stdexec) target_link_libraries(test.stdexec PUBLIC @@ -159,7 +166,10 @@ if(STDEXEC_BUILD_PARALLEL_SCHEDULER AND NOT STDEXEC_ENABLE_CUDA) catch_discover_tests(test.parallel_scheduler_replacement PROPERTIES TIMEOUT 30) endif() -add_subdirectory(exec) +if(!STDEXEC_BUILD_MODULES) + # temporarily speed up the test cycle by building less + add_subdirectory(exec) +endif() if(STDEXEC_ENABLE_CUDA) add_subdirectory(nvexec) diff --git a/test/stdexec/module/test_module.cpp b/test/stdexec/module/test_module.cpp new file mode 100644 index 000000000..8d8a8c4a9 --- /dev/null +++ b/test/stdexec/module/test_module.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2026 Ian Petersen + * Copyright (c) 2026 NVIDIA Corporation + * + * Licensed under the Apache License Version 2.0 with LLVM Exceptions + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * https://llvm.org/LICENSE.txt + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +import std; +import stdexec; + +namespace ex = stdexec; + +namespace +{ + TEST_CASE("I can use ex::just in a modules build", "[modules]") + { + STATIC_REQUIRE(sizeof(ex::just_t) > 0); + } +} // namespace From 4025a1f790fabcda110ad7c720c823d51f498cab Mon Sep 17 00:00:00 2001 From: Ian Petersen Date: Fri, 24 Jul 2026 09:03:36 -0700 Subject: [PATCH 2/4] Almost-working modules build This diff doesn't build for a very exciting reson: the new modules-only test shows that `stdexec::just_t` hasn't been exported from the module. --- include/stdexec/__detail/__any.hpp | 65 +++++++------ include/stdexec/__detail/__as_awaitable.hpp | 65 +++++++------ include/stdexec/__detail/__associate.hpp | 56 ++++++----- include/stdexec/__detail/__atomic.hpp | 51 ++++++---- include/stdexec/__detail/__basic_sender.hpp | 67 +++++++------ .../__detail/__completion_behavior.hpp | 32 ++++--- .../stdexec/__detail/__completion_info.hpp | 37 +++++--- .../__detail/__completion_signatures.hpp | 47 ++++++---- include/stdexec/__detail/__concepts.hpp | 40 +++++--- include/stdexec/__detail/__config.hpp | 34 +++++-- .../stdexec/__detail/__connect_awaitable.hpp | 40 +++++--- .../stdexec/__detail/__counting_scopes.hpp | 51 ++++++---- include/stdexec/__detail/__debug.hpp | 31 +++++-- include/stdexec/__detail/__diagnostics.hpp | 41 +++++--- include/stdexec/__detail/__domain.hpp | 36 ++++--- include/stdexec/__detail/__env.hpp | 33 ++++--- include/stdexec/__detail/__execution_fwd.hpp | 27 ++++-- .../__detail/__get_completion_signatures.hpp | 59 +++++++----- include/stdexec/__detail/__into_variant.hpp | 39 +++++--- include/stdexec/__detail/__intrusive_ptr.hpp | 36 ++++--- .../stdexec/__detail/__intrusive_queue.hpp | 19 +++- .../stdexec/__detail/__intrusive_slist.hpp | 21 +++-- include/stdexec/__detail/__let.hpp | 47 ++++++---- .../stdexec/__detail/__manual_lifetime.hpp | 23 +++-- include/stdexec/__detail/__memory.hpp | 24 +++-- include/stdexec/__detail/__meta.hpp | 66 +++++++------ .../stdexec/__detail/__operation_states.hpp | 23 +++-- include/stdexec/__detail/__optional.hpp | 31 +++++-- .../stdexec/__detail/__parallel_scheduler.hpp | 93 +++++++++++-------- .../__detail/__parallel_scheduler_backend.hpp | 47 ++++++---- .../__parallel_scheduler_replacement_api.hpp | 21 ++++- include/stdexec/__detail/__query.hpp | 27 ++++-- include/stdexec/__detail/__ranges.hpp | 17 +++- include/stdexec/__detail/__read_env.hpp | 45 +++++---- include/stdexec/__detail/__receivers.hpp | 29 ++++-- include/stdexec/__detail/__run_loop.hpp | 35 ++++--- include/stdexec/__detail/__scope.hpp | 18 +++- include/stdexec/__detail/__scope_concepts.hpp | 29 ++++-- .../__detail/__sender_introspection.hpp | 59 +++++++----- include/stdexec/__detail/__spawn.hpp | 43 +++++---- include/stdexec/__detail/__spawn_common.hpp | 23 +++-- include/stdexec/__detail/__spawn_future.hpp | 53 ++++++----- .../stdexec/__detail/__spin_loop_pause.hpp | 4 +- include/stdexec/__detail/__static_vector.hpp | 25 +++-- include/stdexec/__detail/__stop_token.hpp | 33 ++++--- include/stdexec/__detail/__stop_when.hpp | 35 ++++--- .../__detail/__stopped_as_optional.hpp | 39 +++++--- include/stdexec/__detail/__sync_wait.hpp | 55 ++++++----- include/stdexec/__detail/__task.hpp | 42 +++++---- include/stdexec/__detail/__task_scheduler.hpp | 89 ++++++++++-------- include/stdexec/__detail/__tuple.hpp | 44 +++++---- include/stdexec/__detail/__type_traits.hpp | 31 ++++--- include/stdexec/__detail/__typeinfo.hpp | 49 ++++++---- include/stdexec/__detail/__utility.hpp | 62 +++++++------ include/stdexec/__detail/__variant.hpp | 37 +++++--- include/stdexec/__detail/__when_all.hpp | 61 +++++++----- include/stdexec/coroutine.hpp | 36 ++++--- include/stdexec/functional.hpp | 18 +++- include/stdexec/stop_token.hpp | 45 +++++---- modules/stdexec.cppm | 2 + test/CMakeLists.txt | 27 ++++-- test/stdexec/module/test_module.cpp | 2 +- 62 files changed, 1526 insertions(+), 890 deletions(-) diff --git a/include/stdexec/__detail/__any.hpp b/include/stdexec/__detail/__any.hpp index 9b36f791e..faea56a43 100644 --- a/include/stdexec/__detail/__any.hpp +++ b/include/stdexec/__detail/__any.hpp @@ -15,25 +15,35 @@ */ #pragma once -#include "__concepts.hpp" #include "__config.hpp" -#include "__memory.hpp" -#include "__type_traits.hpp" -#include "__typeinfo.hpp" -#include "__utility.hpp" -#include -#include -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include -#include -#include -#include -#include -#include +import stdexec; -#include "__prologue.hpp" +#else + +# include "__concepts.hpp" +# include "__config.hpp" +# include "__memory.hpp" +# include "__type_traits.hpp" +# include "__typeinfo.hpp" +# include "__utility.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include + +# include +# include +# include +# include +# include +# include +# endif + +# include "__prologue.hpp" STDEXEC_PRAGMA_IGNORE_GNU("-Wredundant-consteval-if") STDEXEC_PRAGMA_IGNORE_GNU("-Warray-bounds") @@ -465,7 +475,7 @@ namespace STDEXEC::__any : __val_(static_cast<_Args &&>(__args)...) {} -#if !STDEXEC_GCC() +# if !STDEXEC_GCC() template constexpr explicit __box(__in_place_from_t, _Fn &&__fn, _Args &&...__args) noexcept(__nothrow_callable<_Fn, _Args...>) @@ -473,7 +483,7 @@ namespace STDEXEC::__any { static_assert(__same_as<__call_result_t<_Fn, _Args...>, _Value>); } -#else +# else template constexpr explicit __box(__in_place_from_t, _Fn &&__fn, _Args &&...__args) noexcept(__nothrow_callable<_Fn, _Args...>) @@ -516,7 +526,7 @@ namespace STDEXEC::__any __val_ = __rhs.__val_; return *this; } -#endif +# endif template [[nodiscard]] @@ -526,16 +536,16 @@ namespace STDEXEC::__any } private: -#if !STDEXEC_GCC() +# if !STDEXEC_GCC() STDEXEC_ATTRIBUTE(no_unique_address) _Value __val_; -#else +# else union { STDEXEC_ATTRIBUTE(no_unique_address) _Value __val_; }; -#endif +# endif }; template @@ -1583,28 +1593,28 @@ namespace STDEXEC::__any struct __bad_any_cast : std::exception { [[nodiscard]] -#if __cpp_lib_constexpr_exceptions >= 202502L // constexpr support for std::exception +# if __cpp_lib_constexpr_exceptions >= 202502L // constexpr support for std::exception constexpr -#endif +# endif char const *what() const noexcept override { return "__bad_any_cast"; } }; -#if defined(__cpp_exceptions) && __cpp_exceptions >= 199711L +# if defined(__cpp_exceptions) && __cpp_exceptions >= 199711L [[noreturn]] inline void __throw_bad_any_cast() { throw __bad_any_cast(); } -#else +# else [[noreturn]] inline constexpr void __throw_bad_any_cast() noexcept { STDEXEC::__die("__bad_any_cast\n"); } -#endif +# endif ////////////////////////////////////////////////////////////////////////////////////////// //! __any_static_cast @@ -2254,4 +2264,5 @@ namespace STDEXEC::__any // NOLINTEND(moderize-use-override) -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__as_awaitable.hpp b/include/stdexec/__detail/__as_awaitable.hpp index c56f086fa..a09531918 100644 --- a/include/stdexec/__detail/__as_awaitable.hpp +++ b/include/stdexec/__detail/__as_awaitable.hpp @@ -15,34 +15,44 @@ */ #pragma once -#include "__execution_fwd.hpp" - -#include "../coroutine.hpp" -#include "../functional.hpp" -#include "__atomic.hpp" -#include "__awaitable.hpp" -#include "__completion_signatures_of.hpp" -#include "__concepts.hpp" -#include "__connect.hpp" -#include "__meta.hpp" -#include "__queries.hpp" -#include "__spin_loop_pause.hpp" -#include "__type_traits.hpp" -#include "__variant.hpp" - -#include -#include // for std::identity -#include -#include - -#include "__prologue.hpp" +#include "__config.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" + +# include "../coroutine.hpp" +# include "../functional.hpp" +# include "__atomic.hpp" +# include "__awaitable.hpp" +# include "__completion_signatures_of.hpp" +# include "__concepts.hpp" +# include "__connect.hpp" +# include "__meta.hpp" +# include "__queries.hpp" +# include "__spin_loop_pause.hpp" +# include "__type_traits.hpp" +# include "__variant.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include // for std::identity +# include +# include +# endif + +# include "__prologue.hpp" STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces") STDEXEC_PRAGMA_IGNORE_MSVC(4714) // marked as __forceinline not inlined namespace STDEXEC { -#if !STDEXEC_NO_STDCPP_COROUTINES() +# if !STDEXEC_NO_STDCPP_COROUTINES() ///////////////////////////////////////////////////////////////////////////// // STDEXEC::as_awaitable [exec.as.awaitable] @@ -332,17 +342,17 @@ namespace STDEXEC // finished and won't access the frame anymore. // We do this with an exchange({}), except on buggy MSVC versions, where we have to delay // the signaling until we exited this function. -# if !defined(STDEXEC_MSVC_CORO_DESTROY_BUG_WORKAROUND) +# if !defined(STDEXEC_MSVC_CORO_DESTROY_BUG_WORKAROUND) bool const __done = // this->__thread_id_.exchange(std::thread::id{}, __std::memory_order_release) == std::thread::id{}; return __done ? this->__get_continuation() : __std::noop_coroutine(); -# else +# else bool const __done = // this->__thread_id_.load(__std::memory_order_relaxed) == std::thread::id{}; return __done ? this->__get_continuation() : __coroutine_signal_completion(this->__thread_id_); -# endif +# endif } private: @@ -474,7 +484,8 @@ namespace STDEXEC {}; inline constexpr as_awaitable_t as_awaitable{}; -#endif +# endif } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__associate.hpp b/include/stdexec/__detail/__associate.hpp index 38b1033e6..9f1cf8076 100644 --- a/include/stdexec/__detail/__associate.hpp +++ b/include/stdexec/__detail/__associate.hpp @@ -16,27 +16,36 @@ */ #pragma once -#include "__execution_fwd.hpp" - -#include "__basic_sender.hpp" -#include "__completion_signatures.hpp" -#include "__concepts.hpp" #include "__config.hpp" -#include "__operation_states.hpp" -#include "__receivers.hpp" -#include "__scope_concepts.hpp" -#include "__sender_adaptor_closure.hpp" -#include "__sender_concepts.hpp" -#include "__sender_introspection.hpp" -#include "__senders.hpp" -#include "__transform_completion_signatures.hpp" -#include "__type_traits.hpp" - -#include -#include -#include - -#include "__prologue.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" + +# include "__basic_sender.hpp" +# include "__completion_signatures.hpp" +# include "__concepts.hpp" +# include "__operation_states.hpp" +# include "__receivers.hpp" +# include "__scope_concepts.hpp" +# include "__sender_adaptor_closure.hpp" +# include "__sender_concepts.hpp" +# include "__sender_introspection.hpp" +# include "__senders.hpp" +# include "__transform_completion_signatures.hpp" +# include "__type_traits.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -236,11 +245,11 @@ namespace STDEXEC struct __associate_impl : __sexpr_defaults { -#if 0 // TODO: I don't know how to implement this correctly +# if 0 // TODO: I don't know how to implement this correctly static constexpr auto __get_attrs = [](__ignore, const _Child& __child) noexcept { return __sync_attrs{__child}; }; -#endif +# endif template using __wrap_sender_of_t = @@ -288,4 +297,5 @@ namespace STDEXEC {}; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__atomic.hpp b/include/stdexec/__detail/__atomic.hpp index ecf7c0520..d1774dfaa 100644 --- a/include/stdexec/__detail/__atomic.hpp +++ b/include/stdexec/__detail/__atomic.hpp @@ -15,20 +15,32 @@ */ #pragma once -#include "__concepts.hpp" // IWYU pragma: keep for __std::integral #include "__config.hpp" -#if __has_include() -# include -# define STDEXEC_HAS_CUDA_STD_ATOMIC() 1 +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + #else -# include -# define STDEXEC_HAS_CUDA_STD_ATOMIC() 0 -#endif -#include +# include "__concepts.hpp" // IWYU pragma: keep for __std::integral + +# if !STDEXEC_USE_MODULES() +# if __has_include() +# include +# define STDEXEC_HAS_CUDA_STD_ATOMIC() 1 +# else +# include +# define STDEXEC_HAS_CUDA_STD_ATOMIC() 0 +# endif + +# include +# else + // this is the "use-std" case, but we rely on import std +# define STDEXEC_HAS_CUDA_STD_ATOMIC() 0 +# endif -#include "__prologue.hpp" +# include "__prologue.hpp" STDEXEC_PRAGMA_IGNORE_GNU("-Wdeprecated-declarations") STDEXEC_PRAGMA_IGNORE_EDG(deprecated_entity) @@ -36,7 +48,7 @@ STDEXEC_PRAGMA_IGNORE_MSVC(4996) // 'foo': was declared deprecated namespace STDEXEC::__std { -#if STDEXEC_HAS_CUDA_STD_ATOMIC() +# if STDEXEC_HAS_CUDA_STD_ATOMIC() using cuda::std::atomic; using cuda::std::atomic_ref; @@ -51,7 +63,7 @@ namespace STDEXEC::__std using cuda::std::atomic_thread_fence; using cuda::std::atomic_signal_fence; -#else // ^^^ STDEXEC_HAS_CUDA_STD_ATOMIC() / vvv !STDEXEC_HAS_CUDA_STD_ATOMIC() +# else // ^^^ STDEXEC_HAS_CUDA_STD_ATOMIC() / vvv !STDEXEC_HAS_CUDA_STD_ATOMIC() using std::atomic; using std::atomic_flag; @@ -65,9 +77,9 @@ namespace STDEXEC::__std using std::atomic_thread_fence; using std::atomic_signal_fence; -# if __cpp_lib_atomic_ref >= 201806L +# if __cpp_lib_atomic_ref >= 201806L using std::atomic_ref; -# else +# else inline constexpr int __atomic_flag_map[] = { __ATOMIC_RELAXED, __ATOMIC_CONSUME, @@ -110,9 +122,9 @@ namespace STDEXEC::__std __atomic_store_n(__ptr_, __desired, __map_memory_order(__order)); } }; -# endif // ^^^ __cpp_lib_atomic_ref < 201806L +# endif // ^^^ __cpp_lib_atomic_ref < 201806L -#endif // ^^^ !STDEXEC_HAS_CUDA_STD_ATOMIC() +# endif // ^^^ !STDEXEC_HAS_CUDA_STD_ATOMIC() constexpr memory_order __memory_order_load(memory_order __order) noexcept { @@ -121,10 +133,10 @@ namespace STDEXEC::__std : __order; } -#if __cpp_lib_atomic_shared_ptr >= 201711L && !STDEXEC_HAS_CUDA_STD_ATOMIC() +# if __cpp_lib_atomic_shared_ptr >= 201711L && !STDEXEC_HAS_CUDA_STD_ATOMIC() template using __atomic_shared_ptr = std::atomic>; -#else +# else template struct __atomic_shared_ptr { @@ -241,8 +253,9 @@ namespace STDEXEC::__std template __atomic_shared_ptr(std::shared_ptr<_Ty>) -> __atomic_shared_ptr<_Ty>; -#endif // ^^^ __cpp_lib_atomic_shared_ptr < 201711L +# endif // ^^^ __cpp_lib_atomic_shared_ptr < 201711L } // namespace STDEXEC::__std -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__basic_sender.hpp b/include/stdexec/__detail/__basic_sender.hpp index d64ba987b..0b1cb8052 100644 --- a/include/stdexec/__detail/__basic_sender.hpp +++ b/include/stdexec/__detail/__basic_sender.hpp @@ -15,24 +15,34 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" -#include "__completion_signatures_of.hpp" -#include "__concepts.hpp" -#include "__connect.hpp" -#include "__diagnostics.hpp" -#include "__env.hpp" -#include "__memory.hpp" -#include "__meta.hpp" -#include "__operation_states.hpp" -#include "__receivers.hpp" -#include "__sender_introspection.hpp" -#include "__tuple.hpp" -#include "__type_traits.hpp" +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include +import stdexec; -#include "__prologue.hpp" +#else + +# include "__execution_fwd.hpp" + +# include "__completion_signatures_of.hpp" +# include "__concepts.hpp" +# include "__connect.hpp" +# include "__diagnostics.hpp" +# include "__env.hpp" +# include "__memory.hpp" +# include "__meta.hpp" +# include "__operation_states.hpp" +# include "__receivers.hpp" +# include "__sender_introspection.hpp" +# include "__tuple.hpp" +# include "__type_traits.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# endif + +# include "__prologue.hpp" STDEXEC_PRAGMA_IGNORE_GNU("-Wmissing-braces") @@ -41,24 +51,24 @@ namespace STDEXEC ///////////////////////////////////////////////////////////////////////////// // Generic __sender type -#if STDEXEC_EDG() -# define STDEXEC_SEXPR_DESCRIPTOR_FN(_Descriptor) \ +# if STDEXEC_EDG() +# define STDEXEC_SEXPR_DESCRIPTOR_FN(_Descriptor) \ ([](_Desc __desc = {}) { return __desc; }) -# define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child) \ +# define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child) \ STDEXEC::__descriptor_fn<_Tag, _Data, _Child>() -#else // ^^^ EDG ^^^ / vvv !EDG vvv -# define STDEXEC_SEXPR_DESCRIPTOR_FN(_Descriptor) ([] { return _Descriptor(); }) -# define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child) \ +# else // ^^^ EDG ^^^ / vvv !EDG vvv +# define STDEXEC_SEXPR_DESCRIPTOR_FN(_Descriptor) ([] { return _Descriptor(); }) +# define STDEXEC_SEXPR_DESCRIPTOR(_Tag, _Data, _Child) \ STDEXEC::__descriptor_fn_v> -#endif +# endif -#if defined(STDEXEC_DEMANGLE_SENDER_NAMES) +# if defined(STDEXEC_DEMANGLE_SENDER_NAMES) template inline constexpr auto __descriptor_fn_v = _Descriptor{}; -#else +# else template inline constexpr auto __descriptor_fn_v = _DescriptorFn; -#endif +# endif template consteval auto __descriptor_fn() noexcept @@ -236,7 +246,7 @@ namespace STDEXEC using receiver_concept = receiver_tag; using __index_t = __msize_t<_Idx>; -#if STDEXEC_APPLE_CLANG() +# if STDEXEC_APPLE_CLANG() // These constructors are a work-around for bad codegen with apple-clang STDEXEC_ATTRIBUTE(always_inline) constexpr explicit __rcvr(_State& __state) noexcept @@ -247,7 +257,7 @@ namespace STDEXEC constexpr __rcvr(__rcvr const & __other) noexcept : __state_(__other.__state_) {} -#endif // STDEXEC_APPLE_CLANG() +# endif // STDEXEC_APPLE_CLANG() template STDEXEC_ATTRIBUTE(always_inline) @@ -476,4 +486,5 @@ namespace STDEXEC } // namespace __detail } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__completion_behavior.hpp b/include/stdexec/__detail/__completion_behavior.hpp index 6f4bb6b1d..08ca7bcbc 100644 --- a/include/stdexec/__detail/__completion_behavior.hpp +++ b/include/stdexec/__detail/__completion_behavior.hpp @@ -15,18 +15,27 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" // include these after __execution_fwd.hpp -#include "__concepts.hpp" -#include "__config.hpp" -#include "__query.hpp" -#include "__utility.hpp" +# include "__concepts.hpp" +# include "__query.hpp" +# include "__utility.hpp" -#include -#include +# if !STDEXEC_USE_MODULES() +# include +# include +# endif -#include "__prologue.hpp" +# include "__prologue.hpp" namespace STDEXEC { @@ -214,7 +223,7 @@ namespace STDEXEC return __completion_behavior_of_v<_Tag, env_of_t<_Sndr>, _Env...>; } -#if !defined(STDEXEC_DOXYGEN_INVOKED) +# if !defined(STDEXEC_DOXYGEN_INVOKED) struct [[deprecated("Use exec::completion_behavior from " " instead")]] completion_behavior @@ -246,8 +255,9 @@ namespace STDEXEC } // clang-format on -#endif // !defined(STDEXEC_DOXYGEN_INVOKED) +# endif // !defined(STDEXEC_DOXYGEN_INVOKED) } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__completion_info.hpp b/include/stdexec/__detail/__completion_info.hpp index 2b4d845d8..39968479b 100644 --- a/include/stdexec/__detail/__completion_info.hpp +++ b/include/stdexec/__detail/__completion_info.hpp @@ -15,23 +15,35 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" // IWYU pragma: begin_keep -#include "__completion_behavior.hpp" -#include "__completion_signatures.hpp" -#include "__meta.hpp" -#include "__static_vector.hpp" -#include "__typeinfo.hpp" +# include "__completion_behavior.hpp" +# include "__completion_signatures.hpp" +# include "__meta.hpp" +# include "__static_vector.hpp" +# include "__typeinfo.hpp" -#include "../functional.hpp" +# include "../functional.hpp" +// IWYU pragma: end_keep -#include -#include -#include +# if !STDEXEC_USE_MODULES() +// IWYU pragma: begin_keep +# include +# include +# include // IWYU pragma: end_keep +# endif -#include "__prologue.hpp" +# include "__prologue.hpp" namespace STDEXEC { @@ -154,4 +166,5 @@ namespace STDEXEC } // namespace __cmplsigs } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__completion_signatures.hpp b/include/stdexec/__detail/__completion_signatures.hpp index c67e978a8..489904d12 100644 --- a/include/stdexec/__detail/__completion_signatures.hpp +++ b/include/stdexec/__detail/__completion_signatures.hpp @@ -15,19 +15,29 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" // include these after __execution_fwd.hpp -#include "__concepts.hpp" -#include "__diagnostics.hpp" -#include "__meta.hpp" -#include "__tuple.hpp" // IWYU pragma: keep for __tuple -#include "__utility.hpp" +# include "__concepts.hpp" +# include "__diagnostics.hpp" +# include "__meta.hpp" +# include "__tuple.hpp" // IWYU pragma: keep for __tuple +# include "__utility.hpp" -#include -#include +# if !STDEXEC_USE_MODULES() +# include +# include +# endif -#include "__prologue.hpp" +# include "__prologue.hpp" namespace STDEXEC { @@ -438,7 +448,7 @@ namespace STDEXEC template using __eptr_completion_unless_t = __if<_NoExcept, completion_signatures<>, __eptr_completion_t>; -#if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() +# if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() template [[nodiscard]] @@ -454,7 +464,7 @@ namespace STDEXEC return {}; } -#else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv +# else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv // C++26, https://wg21.link/p3068 template @@ -483,7 +493,7 @@ namespace STDEXEC static_cast<_Values>(__values)...); } -#endif // ^^^ constexpr exceptions ^^^ +# endif // ^^^ constexpr exceptions ^^^ template [[nodiscard]] @@ -552,9 +562,9 @@ namespace STDEXEC // Below is the definition of the STDEXEC_IF_OK portability macro. It is used to check // that an expression's type is not an __mexception type. -#if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() +# if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() -# define STDEXEC_IF_OK(_ID) \ +# define STDEXEC_IF_OK(_ID) \ if constexpr (STDEXEC::__merror) \ { \ return _ID; \ @@ -574,9 +584,9 @@ namespace STDEXEC return {}; } -#else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv +# else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv -# define STDEXEC_IF_OK(_ID) +# define STDEXEC_IF_OK(_ID) template [[noreturn, nodiscard]] @@ -592,7 +602,8 @@ namespace STDEXEC throw __dependent_sender_error_t<_Sndr>{}; } -#endif // ^^^ constexpr exceptions ^^^ +# endif // ^^^ constexpr exceptions ^^^ } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__concepts.hpp b/include/stdexec/__detail/__concepts.hpp index 094a2505c..586ff5754 100644 --- a/include/stdexec/__detail/__concepts.hpp +++ b/include/stdexec/__detail/__concepts.hpp @@ -20,18 +20,27 @@ #endif #include "__config.hpp" -#include "__type_traits.hpp" -#include // IWYU pragma: keep for std::swap -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; -#if !STDEXEC_NO_STDCPP_CONCEPTS_HEADER() -# include #else -# include -#endif -#include "__prologue.hpp" +# include "__type_traits.hpp" + +# if !STDEXEC_USE_MODULES() +# include // IWYU pragma: keep for std::swap +# include + +# if !STDEXEC_NO_STDCPP_CONCEPTS_HEADER() +# include +# else +# include +# endif +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -123,14 +132,14 @@ namespace STDEXEC template concept same_as = __same_as<_Ap, _Bp> && __same_as<_Bp, _Ap>; -#if !STDEXEC_NO_STDCPP_CONCEPTS_HEADER() +# if !STDEXEC_NO_STDCPP_CONCEPTS_HEADER() using std::integral; using std::derived_from; using std::convertible_to; using std::equality_comparable; -#else +# else template concept integral = std::is_integral_v; @@ -148,7 +157,7 @@ namespace STDEXEC { __t == __t } -> convertible_to; { __t != __t } -> convertible_to; }; -#endif +# endif } // namespace __std // Not exactly right, but close. @@ -178,13 +187,13 @@ namespace STDEXEC // Avoid using libstdc++'s object concepts because they instantiate a // LOT of templates. -#if STDEXEC_HAS_BUILTIN(__is_nothrow_destructible) || STDEXEC_MSVC() +# if STDEXEC_HAS_BUILTIN(__is_nothrow_destructible) || STDEXEC_MSVC() template concept destructible = __is_nothrow_destructible(_Ty); -#else // ^^^ has __is_nothrow_destructible / no __is_nothrow_destructible vvv +# else // ^^^ has __is_nothrow_destructible / no __is_nothrow_destructible vvv template concept destructible = __detail::__destructible_; -#endif // ^^^ no __is_nothrow_destructible +# endif // ^^^ no __is_nothrow_destructible template concept constructible_from = destructible<_Ty> && STDEXEC_IS_CONSTRUCTIBLE(_Ty, _As...); @@ -344,4 +353,5 @@ namespace STDEXEC && __std::equality_comparable<_Alloc>; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__config.hpp b/include/stdexec/__detail/__config.hpp index 3d8f1aae4..089b2b920 100644 --- a/include/stdexec/__detail/__config.hpp +++ b/include/stdexec/__detail/__config.hpp @@ -38,16 +38,20 @@ #include "__preprocessor.hpp" -#if __has_include() -# include +#if STDEXEC_USE_MODULES() +import std; #else -# include // For stdlib feature-test macros when is not available -#endif +# if __has_include() +# include +# else +# include // For stdlib feature-test macros when is not available +# endif -#include -#include -#include // IWYU pragma: keep -#include // IWYU pragma: keep for std::unreachable +# include +# include +# include // IWYU pragma: keep +# include // IWYU pragma: keep for std::unreachable +#endif // When used with no arguments, these macros expand to 1 if the current // compiler corresponds to the macro name; 0, otherwise. When used with arguments, @@ -212,6 +216,8 @@ STDEXEC_NAMESPACE_STD_END //////////////////////////////////////////////////////////////////////////////////////////////////// #if !defined(STDEXEC_NAMESPACE) # define STDEXEC stdexec +#elif STDEXEC_USE_MODULES() +# define STDEXEC stdexec #else # define STDEXEC STDEXEC_NAMESPACE #endif @@ -247,7 +253,10 @@ STDEXEC_NAMESPACE_STD_END //////////////////////////////////////////////////////////////////////////////////////////////////// #if __cpp_impl_coroutine >= 201902L && __cpp_lib_coroutine >= 201902L -# include // IWYU pragma: keep +# if !STDEXEC_USE_MODULES() + // we've already imported std above +# include // IWYU pragma: keep +# endif # define STDEXEC_NO_STDCPP_COROUTINES() 0 namespace STDEXEC::__std { @@ -575,6 +584,8 @@ namespace STDEXEC #endif #if STDEXEC_NVHPC() +// TODO: this is probably wrong in modules builds, but I don't know if there's an +// nv-prefixed build that can enable modules # include # define STDEXEC_TERMINATE() NV_IF_TARGET(NV_IS_HOST, (std::terminate();), (__trap();)) void() #elif STDEXEC_CLANG() && defined(__CUDA__) && defined(__CUDA_ARCH__) @@ -715,6 +726,7 @@ namespace STDEXEC // clang-format off #if STDEXEC_HAS_CTK() && __has_include() +// TODO: probably wrong with modules, but do nv-prefixed builds care? # include # define STDEXEC_IF_HOST(...) NV_IF_TARGET(NV_IS_HOST, (__VA_ARGS__;)) # define STDEXEC_IF_DEVICE(...) NV_IF_TARGET(NV_IS_DEVICE, (__VA_ARGS__;)) @@ -727,6 +739,7 @@ namespace STDEXEC // CUDA compilers preinclude cuda_runtime.h, but if we're not compiling for CUDA then we // need to include it ourselves. #if STDEXEC_HAS_CTK() && !STDEXEC_CUDA_COMPILATION() +// TODO: probably wrong with modules, but do nv-prefixed builds care? # include #endif @@ -766,6 +779,7 @@ namespace STDEXEC // clang-format on +#if !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) namespace STDEXEC { // Used by the STDEXEC_CATCH macro to provide a stub initialization of the exception object. @@ -784,6 +798,7 @@ namespace STDEXEC STDEXEC_UNREACHABLE(); } } // namespace STDEXEC +#endif #if defined(STDEXEC_ASSERT) // nothing to do, user has provided their own assertion macro @@ -917,6 +932,7 @@ namespace STDEXEC //////////////////////////////////////////////////////////////////////////////////////////////////// // clang-tidy struggles with the CUDA function annotations #if STDEXEC_CLANG() && STDEXEC_CUDA_COMPILATION() && defined(STDEXEC_CLANG_TIDY_INVOKED) +// TODO: probably wrong with modules, but do nv-prefixed builds care? # include // IWYU pragma: keep # if !defined(__launch_bounds__) # define __launch_bounds__(...) diff --git a/include/stdexec/__detail/__connect_awaitable.hpp b/include/stdexec/__detail/__connect_awaitable.hpp index b13f76965..5ae3a277f 100644 --- a/include/stdexec/__detail/__connect_awaitable.hpp +++ b/include/stdexec/__detail/__connect_awaitable.hpp @@ -15,26 +15,35 @@ */ #pragma once -#include "__execution_fwd.hpp" - -#include "../coroutine.hpp" -#include "__awaitable.hpp" -#include "__concepts.hpp" #include "__config.hpp" -#include "__env.hpp" -#include "__manual_lifetime.hpp" -#include "__receivers.hpp" -#include "__scope.hpp" -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" + +# include "../coroutine.hpp" +# include "__awaitable.hpp" +# include "__concepts.hpp" +# include "__env.hpp" +# include "__manual_lifetime.hpp" +# include "__receivers.hpp" +# include "__scope.hpp" -#include "__prologue.hpp" +# if !STDEXEC_USE_MODULES() +# include +# endif + +# include "__prologue.hpp" STDEXEC_PRAGMA_IGNORE_GNU("-Wsubobject-linkage") namespace STDEXEC { -#if !STDEXEC_NO_STDCPP_COROUTINES() +# if !STDEXEC_NO_STDCPP_COROUTINES() ///////////////////////////////////////////////////////////////////////////// // __connect_await namespace __connect_await @@ -514,7 +523,7 @@ namespace STDEXEC } }; -#else +# else namespace __connect_await { @@ -530,9 +539,10 @@ namespace STDEXEC struct __connect_awaitable_t {}; -#endif +# endif inline constexpr __connect_awaitable_t __connect_awaitable{}; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__counting_scopes.hpp b/include/stdexec/__detail/__counting_scopes.hpp index aee4e6750..5e11d282b 100644 --- a/include/stdexec/__detail/__counting_scopes.hpp +++ b/include/stdexec/__detail/__counting_scopes.hpp @@ -16,25 +16,35 @@ */ #pragma once -#include "__execution_fwd.hpp" - -#include "../stop_token.hpp" // IWYU pragma: keep for inplace_stop_source -#include "__atomic.hpp" -#include "__concepts.hpp" -#include "__env.hpp" -#include "__receivers.hpp" -#include "__schedulers.hpp" -#include "__sender_concepts.hpp" -#include "__stop_when.hpp" - -#include -#include -#include -#include -#include -#include - -#include "__prologue.hpp" +#include "__config.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" + +# include "../stop_token.hpp" // IWYU pragma: keep for inplace_stop_source +# include "__atomic.hpp" +# include "__concepts.hpp" +# include "__env.hpp" +# include "__receivers.hpp" +# include "__schedulers.hpp" +# include "__sender_concepts.hpp" +# include "__stop_when.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# include +# include +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -869,4 +879,5 @@ namespace STDEXEC }; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__debug.hpp b/include/stdexec/__detail/__debug.hpp index daf98f052..ea9d5ba41 100644 --- a/include/stdexec/__detail/__debug.hpp +++ b/include/stdexec/__detail/__debug.hpp @@ -15,18 +15,28 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" -#include "__completion_signatures.hpp" -#include "__concepts.hpp" -#include "__env.hpp" // IWYU pragma: keep for env<> -#include "__meta.hpp" -#include "__query.hpp" -#include "__sender_concepts.hpp" +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include // IWYU pragma: keep for std::terminate +import stdexec; -#include "__prologue.hpp" +#else + +# include "__execution_fwd.hpp" + +# include "__completion_signatures.hpp" +# include "__concepts.hpp" +# include "__env.hpp" // IWYU pragma: keep for env<> +# include "__meta.hpp" +# include "__query.hpp" +# include "__sender_concepts.hpp" + +# if !STDEXEC_USE_MODULES() +# include // IWYU pragma: keep for std::terminate +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -215,4 +225,5 @@ namespace STDEXEC } } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__diagnostics.hpp b/include/stdexec/__detail/__diagnostics.hpp index b587daaf8..ef45f384e 100644 --- a/include/stdexec/__detail/__diagnostics.hpp +++ b/include/stdexec/__detail/__diagnostics.hpp @@ -15,14 +15,24 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" + +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" // include these after __execution_fwd.hpp -#include "__meta.hpp" +# include "__meta.hpp" -#include // IWYU pragma: keep for std::exception +# if !STDEXEC_USE_MODULES() +# include // IWYU pragma: keep for std::exception +# endif -#include "__prologue.hpp" +# include "__prologue.hpp" namespace STDEXEC { @@ -146,12 +156,12 @@ namespace STDEXEC _WITH_PRETTY_SENDER_<_Sender>, _WITH_ENVIRONMENT_(_Env)...>; -#if __cpp_lib_constexpr_exceptions >= 202502L +# if __cpp_lib_constexpr_exceptions >= 202502L // constexpr stdlib exception types, https://wg21.link/p3378 using __exception = ::std::exception; -#elif __cpp_constexpr >= 201907L && !STDEXEC_MSVC() && !STDEXEC_NVHPC() +# elif __cpp_constexpr >= 201907L && !STDEXEC_MSVC() && !STDEXEC_NVHPC() // constexpr virtual functions struct __exception @@ -166,7 +176,7 @@ namespace STDEXEC } }; -#else +# else // no constexpr virtual functions struct __exception @@ -180,7 +190,7 @@ namespace STDEXEC } }; -#endif // __cpp_lib_constexpr_exceptions >= 202502L +# endif // __cpp_lib_constexpr_exceptions >= 202502L struct __compile_time_error : __exception {}; @@ -296,7 +306,7 @@ namespace STDEXEC } // namespace STDEXEC //////////////////////////////////////////////////////////////////////////////// -#define STDEXEC_ERROR_ENABLE_SENDER_IS_FALSE \ +# define STDEXEC_ERROR_ENABLE_SENDER_IS_FALSE \ "\n" \ "\n" \ "The given type is not a sender because " STDEXEC_PP_STRINGIZE(STDEXEC) "::enable_sender"\ @@ -327,7 +337,7 @@ namespace STDEXEC " inline constexpr bool " STDEXEC_PP_STRINGIZE(STDEXEC) "::enable_sender = true;\n" //////////////////////////////////////////////////////////////////////////////// -#define STDEXEC_ERROR_CANNOT_COMPUTE_COMPLETION_SIGNATURES \ +# define STDEXEC_ERROR_CANNOT_COMPUTE_COMPLETION_SIGNATURES \ "\n" \ "\n" \ "The sender type was not able to report its completion signatures when asked.\n" \ @@ -378,13 +388,13 @@ namespace STDEXEC " };\n" //////////////////////////////////////////////////////////////////////////////// -#define STDEXEC_ERROR_GET_COMPLETION_SIGNATURES_RETURNED_AN_ERROR \ +# define STDEXEC_ERROR_GET_COMPLETION_SIGNATURES_RETURNED_AN_ERROR \ "\n" \ "\n" \ "Trying to compute the sender's completion signatures resulted in an error. See\n" \ "the rest of the compiler diagnostic for clues. Look for the string \"_ERROR_\".\n" -#define STDEXEC_ERROR_GET_COMPLETION_SIGNATURES_HAS_INVALID_RETURN_TYPE \ +# define STDEXEC_ERROR_GET_COMPLETION_SIGNATURES_HAS_INVALID_RETURN_TYPE \ "\n" \ "\n" \ "The member function 'get_completion_signatures' of the sender returned an\n" \ @@ -412,7 +422,7 @@ namespace STDEXEC " };\n" //////////////////////////////////////////////////////////////////////////////// -#define STDEXEC_ERROR_CANNOT_CONNECT_SENDER_TO_RECEIVER \ +# define STDEXEC_ERROR_CANNOT_CONNECT_SENDER_TO_RECEIVER \ "\n" \ "A sender must provide a 'connect' member function that takes a receiver as an\n" \ "argument and returns an object whose type satisfies '" STDEXEC_PP_STRINGIZE(STDEXEC) \ @@ -450,7 +460,7 @@ namespace STDEXEC " };\n" //////////////////////////////////////////////////////////////////////////////// -#define STDEXEC_ERROR_SYNC_WAIT_CANNOT_CONNECT_SENDER_TO_RECEIVER \ +# define STDEXEC_ERROR_SYNC_WAIT_CANNOT_CONNECT_SENDER_TO_RECEIVER \ "\n" \ "\n" \ "The sender passed to '" STDEXEC_PP_STRINGIZE(STDEXEC) "::sync_wait()' does not have a " \ @@ -458,4 +468,5 @@ namespace STDEXEC "member function that accepts sync_wait's receiver.\n" \ STDEXEC_ERROR_CANNOT_CONNECT_SENDER_TO_RECEIVER -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__domain.hpp b/include/stdexec/__detail/__domain.hpp index d1f8a056d..77bed3190 100644 --- a/include/stdexec/__detail/__domain.hpp +++ b/include/stdexec/__detail/__domain.hpp @@ -15,18 +15,27 @@ */ #pragma once -#include "__execution_fwd.hpp" - -#include "__completion_behavior.hpp" -#include "__concepts.hpp" #include "__config.hpp" -#include "__meta.hpp" -#include "__sender_introspection.hpp" -#include "__utility.hpp" -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else + +# include "__execution_fwd.hpp" + +# include "__completion_behavior.hpp" +# include "__concepts.hpp" +# include "__meta.hpp" +# include "__sender_introspection.hpp" +# include "__utility.hpp" -#include "__prologue.hpp" +# if !STDEXEC_USE_MODULES() +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -448,10 +457,10 @@ namespace STDEXEC } }; -#if !STDEXEC_GCC() || defined(__OPTIMIZE_SIZE__) +# if !STDEXEC_GCC() || defined(__OPTIMIZE_SIZE__) template inline constexpr get_completion_domain_t<_Tag> get_completion_domain{}; -#else +# else template <> inline constexpr get_completion_domain_t<> get_completion_domain<>{}; template <> @@ -460,7 +469,7 @@ namespace STDEXEC inline constexpr get_completion_domain_t get_completion_domain{}; template <> inline constexpr get_completion_domain_t get_completion_domain{}; -#endif +# endif inline constexpr get_domain_t get_domain{}; } // namespace STDEXEC @@ -490,4 +499,5 @@ namespace std } // namespace std -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__env.hpp b/include/stdexec/__detail/__env.hpp index 89994a413..2becff199 100644 --- a/include/stdexec/__detail/__env.hpp +++ b/include/stdexec/__detail/__env.hpp @@ -15,19 +15,29 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" -#include "__concepts.hpp" -#include "__meta.hpp" -#include "__query.hpp" -#include "__tag_invoke.hpp" -#include "__tuple.hpp" +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include // IWYU pragma: keep for std::terminate -#include // IWYU pragma: keep for unwrap_reference_t -#include +import stdexec; -#include "__prologue.hpp" +#else + +# include "__execution_fwd.hpp" + +# include "__concepts.hpp" +# include "__meta.hpp" +# include "__query.hpp" +# include "__tag_invoke.hpp" +# include "__tuple.hpp" + +# if !STDEXEC_USE_MODULES() +# include // IWYU pragma: keep for std::terminate +# include // IWYU pragma: keep for unwrap_reference_t +# include +# endif + +# include "__prologue.hpp" STDEXEC_PRAGMA_IGNORE_EDG(probable_guiding_friend) STDEXEC_PRAGMA_IGNORE_EDG(type_qualifiers_ignored_on_reference) @@ -373,4 +383,5 @@ namespace STDEXEC concept __environment_provider = __minvocable_q<__call_result_t, get_env_t, _EnvProvider const &>; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__execution_fwd.hpp b/include/stdexec/__detail/__execution_fwd.hpp index d7852d2bf..adc4ee2c5 100644 --- a/include/stdexec/__detail/__execution_fwd.hpp +++ b/include/stdexec/__detail/__execution_fwd.hpp @@ -19,13 +19,20 @@ #include "__config.hpp" // IWYU pragma: export -#include "__concepts.hpp" -#include "__meta.hpp" -#include "__type_traits.hpp" -#include "__utility.hpp" +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include "__prologue.hpp" +import stdexec; +#else + +# include "__concepts.hpp" +# include "__meta.hpp" +# include "__type_traits.hpp" +# include "__utility.hpp" + +# include "__prologue.hpp" + +# if !STDEXEC_USE_MODULES() STDEXEC_NAMESPACE_STD_BEGIN struct monostate; @@ -35,6 +42,7 @@ STDEXEC_NAMESPACE_STD_BEGIN template class tuple; STDEXEC_NAMESPACE_STD_END +# endif namespace STDEXEC { @@ -198,20 +206,20 @@ namespace STDEXEC using __cmplsigs::get_completion_signatures_t; -#if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() +# if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() template [[nodiscard]] consteval auto __throw_compile_time_error(_Values...) -> __mexception<_What...>; -#else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv +# else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv // C++26, https://wg21.link/p3068 template [[noreturn, nodiscard]] consteval auto __throw_compile_time_error(_Values...) -> completion_signatures<>; -#endif // ^^^ constexpr exceptions ^^^ +# endif // ^^^ constexpr exceptions ^^^ template [[nodiscard]] @@ -407,4 +415,5 @@ namespace STDEXEC STDEXEC_P2300_DEPRECATED_SYMBOL(std::this_thread::sync_wait_with_variant) } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__get_completion_signatures.hpp b/include/stdexec/__detail/__get_completion_signatures.hpp index 5435cfb8b..28749af33 100644 --- a/include/stdexec/__detail/__get_completion_signatures.hpp +++ b/include/stdexec/__detail/__get_completion_signatures.hpp @@ -15,22 +15,32 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" -// include these after __execution_fwd.hpp -#include "__awaitable.hpp" -#include "__completion_info.hpp" -#include "__completion_signatures.hpp" // IWYU pragma: export -#include "__connect_awaitable.hpp" -#include "__diagnostics.hpp" -#include "__env.hpp" -#include "__meta.hpp" -#include "__tag_invoke.hpp" -#include "__tuple.hpp" // IWYU pragma: keep for __tuple +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; + +#else -#include +# include "__execution_fwd.hpp" -#include "__prologue.hpp" +// include these after __execution_fwd.hpp +# include "__awaitable.hpp" +# include "__completion_info.hpp" +# include "__completion_signatures.hpp" // IWYU pragma: export +# include "__connect_awaitable.hpp" +# include "__diagnostics.hpp" +# include "__env.hpp" +# include "__meta.hpp" +# include "__tag_invoke.hpp" +# include "__tuple.hpp" // IWYU pragma: keep for __tuple + +# if !STDEXEC_USE_MODULES() +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -58,11 +68,11 @@ namespace STDEXEC namespace __cmplsigs { -#define STDEXEC_GET_COMPLSIGS(...) \ +# define STDEXEC_GET_COMPLSIGS(...) \ STDEXEC_REMOVE_REFERENCE( \ STDEXEC_PP_FRONT(__VA_ARGS__))::template get_completion_signatures<__VA_ARGS__>() -#define STDEXEC_CHECKED_COMPLSIGS(_ARGS, ...) \ +# define STDEXEC_CHECKED_COMPLSIGS(_ARGS, ...) \ STDEXEC::__cmplsigs::__checked_complsigs( \ __VA_ARGS__, static_cast<__mlist*>(nullptr)) @@ -381,14 +391,14 @@ namespace STDEXEC /////////////////////////////////////////////////////////////////////////////////////////////////// // An minimally constrained alias for the result of get_completion_signatures: -#if STDEXEC_GCC() +# if STDEXEC_GCC() template requires enable_sender<__decay_t<_Sender>> && __constant()> using __completion_signatures_of_t = decltype(STDEXEC::get_completion_signatures<_Sender, _Env...>()); -#elif STDEXEC_EDG() +# elif STDEXEC_EDG() namespace __detail { @@ -404,7 +414,7 @@ namespace STDEXEC using __completion_signatures_of_t = decltype(STDEXEC::get_completion_signatures<_Sender, _Env...>()); -#elif STDEXEC_MSVC() +# elif STDEXEC_MSVC() // MSVC cannot handle a __completion_signatures_of_t alias template that requires // get_completion_signatures to be a constant expression, even if we wrap the call to @@ -416,13 +426,13 @@ namespace STDEXEC using __completion_signatures_of_t = decltype(STDEXEC::get_completion_signatures<_Sender, _Env...>()); -#else +# else template requires enable_sender<__decay_t<_Sender>> using __completion_signatures_of_t = __mtypeof()>; -#endif +# endif /////////////////////////////////////////////////////////////////////////////////////////////////// // __get_child_completion_signatures @@ -434,11 +444,11 @@ namespace STDEXEC __fwd_env_t<_Env>...>(); } -#if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() +# if STDEXEC_NO_STDCPP_CONSTEXPR_EXCEPTIONS() template concept __is_dependent_sender = __std::derived_from<__completion_signatures_of_t<_Sender>, dependent_sender_error>; -#else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv +# else // ^^^ no constexpr exceptions ^^^ / vvv constexpr exceptions vvv // When asked for its completions without an envitonment, a dependent sender // will throw an exception of a type derived from `dependent_sender_error`. template @@ -460,7 +470,7 @@ namespace STDEXEC template concept __is_dependent_sender = __mbool<__is_dependent_sender_helper<_Sender>()>::value; -#endif // ^^^ constexpr exceptions ^^^ +# endif // ^^^ constexpr exceptions ^^^ template using __gather_completions_of_t = @@ -516,4 +526,5 @@ namespace STDEXEC } } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__into_variant.hpp b/include/stdexec/__detail/__into_variant.hpp index 1dec4cacf..2b2134a10 100644 --- a/include/stdexec/__detail/__into_variant.hpp +++ b/include/stdexec/__detail/__into_variant.hpp @@ -15,22 +15,32 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" -// include these after __execution_fwd.hpp -#include "__basic_sender.hpp" -#include "__concepts.hpp" -#include "__meta.hpp" -#include "__sender_adaptor_closure.hpp" -#include "__senders.hpp" // IWYU pragma: keep for __well_formed_sender -#include "__transform_completion_signatures.hpp" -#include "__utility.hpp" +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; -#include -#include -#include // IWYU pragma: keep +#else -#include "__prologue.hpp" +# include "__execution_fwd.hpp" + +// include these after __execution_fwd.hpp +# include "__basic_sender.hpp" +# include "__concepts.hpp" +# include "__meta.hpp" +# include "__sender_adaptor_closure.hpp" +# include "__senders.hpp" // IWYU pragma: keep for __well_formed_sender +# include "__transform_completion_signatures.hpp" +# include "__utility.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include // IWYU pragma: keep +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -228,4 +238,5 @@ namespace STDEXEC {}; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__intrusive_ptr.hpp b/include/stdexec/__detail/__intrusive_ptr.hpp index 7a5cb6977..ba8543143 100644 --- a/include/stdexec/__detail/__intrusive_ptr.hpp +++ b/include/stdexec/__detail/__intrusive_ptr.hpp @@ -15,19 +15,32 @@ */ #pragma once -#include "__concepts.hpp" +#include "__config.hpp" -#include "__atomic.hpp" -#include -#include -#include -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#if STDEXEC_TSAN() -# include -#endif +import stdexec; -#include "__prologue.hpp" +#else + +# include "__concepts.hpp" + +# include "__atomic.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# include +# endif + +// TODO: I wonder if this belongs in the GMF in stdexec.cppm +// when we're building for modules. +# if STDEXEC_TSAN() +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -378,4 +391,5 @@ namespace STDEXEC } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__intrusive_queue.hpp b/include/stdexec/__detail/__intrusive_queue.hpp index 653936295..12f8f6f8e 100644 --- a/include/stdexec/__detail/__intrusive_queue.hpp +++ b/include/stdexec/__detail/__intrusive_queue.hpp @@ -18,11 +18,19 @@ #include "__config.hpp" -#include -#include -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include "__prologue.hpp" +import stdexec; + +#else + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -298,4 +306,5 @@ namespace STDEXEC } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__intrusive_slist.hpp b/include/stdexec/__detail/__intrusive_slist.hpp index 0788430e4..9f40d916b 100644 --- a/include/stdexec/__detail/__intrusive_slist.hpp +++ b/include/stdexec/__detail/__intrusive_slist.hpp @@ -17,12 +17,20 @@ #include "__config.hpp" -#include -#include -#include -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include "__prologue.hpp" +import stdexec; + +#else + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -174,4 +182,5 @@ namespace STDEXEC } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__let.hpp b/include/stdexec/__detail/__let.hpp index 3363231c0..d6a5f6dc9 100644 --- a/include/stdexec/__detail/__let.hpp +++ b/include/stdexec/__detail/__let.hpp @@ -15,27 +15,37 @@ */ #pragma once -#include "__execution_fwd.hpp" +#include "__config.hpp" -// include these after __execution_fwd.hpp -#include "__basic_sender.hpp" -#include "__completion_info.hpp" -#include "__diagnostics.hpp" -#include "__domain.hpp" -#include "__env.hpp" -#include "__meta.hpp" -#include "__schedulers.hpp" -#include "__sender_adaptor_closure.hpp" -#include "__senders.hpp" -#include "__submit.hpp" -#include "__utility.hpp" -#include "__variant.hpp" +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) + +import stdexec; -#include "../functional.hpp" +#else -#include +# include "__execution_fwd.hpp" -#include "__prologue.hpp" +// include these after __execution_fwd.hpp +# include "__basic_sender.hpp" +# include "__completion_info.hpp" +# include "__diagnostics.hpp" +# include "__domain.hpp" +# include "__env.hpp" +# include "__meta.hpp" +# include "__schedulers.hpp" +# include "__sender_adaptor_closure.hpp" +# include "__senders.hpp" +# include "__submit.hpp" +# include "__utility.hpp" +# include "__variant.hpp" + +# include "../functional.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -1007,4 +1017,5 @@ namespace STDEXEC {}; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__manual_lifetime.hpp b/include/stdexec/__detail/__manual_lifetime.hpp index 20f0514b9..13da0ad67 100644 --- a/include/stdexec/__detail/__manual_lifetime.hpp +++ b/include/stdexec/__detail/__manual_lifetime.hpp @@ -16,13 +16,23 @@ */ #pragma once -#include "__concepts.hpp" +#include "__config.hpp" -#include -#include -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include "__prologue.hpp" +import stdexec; + +#else + +# include "__concepts.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -176,4 +186,5 @@ namespace STDEXEC }; } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__memory.hpp b/include/stdexec/__detail/__memory.hpp index a499fb09d..41c59b3d3 100644 --- a/include/stdexec/__detail/__memory.hpp +++ b/include/stdexec/__detail/__memory.hpp @@ -15,14 +15,23 @@ */ #pragma once -#include "__execution_fwd.hpp" -#include "__scope.hpp" -#include "__tuple.hpp" +#include "__config.hpp" -// include these after __execution_fwd.hpp -#include // IWYU pragma: export +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include "__prologue.hpp" +import stdexec; + +#else + +# include "__execution_fwd.hpp" +# include "__scope.hpp" +# include "__tuple.hpp" + +# if !STDEXEC_USE_MODULES() +# include // IWYU pragma: export +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -137,4 +146,5 @@ namespace STDEXEC } // namespace STDEXEC -#include "__epilogue.hpp" +# include "__epilogue.hpp" +#endif // !STDEXEC_USE_MODULES() || defined(STDEXEC_IN_MODULE_PURVIEW) diff --git a/include/stdexec/__detail/__meta.hpp b/include/stdexec/__detail/__meta.hpp index 4f0267428..31606f199 100644 --- a/include/stdexec/__detail/__meta.hpp +++ b/include/stdexec/__detail/__meta.hpp @@ -15,18 +15,27 @@ */ #pragma once -#include "__concepts.hpp" #include "__config.hpp" -#include "__type_traits.hpp" -#include "__typeinfo.hpp" -#include -#include -#include -#include -#include +#if STDEXEC_USE_MODULES() && !defined(STDEXEC_IN_MODULE_PURVIEW) -#include "__prologue.hpp" +import stdexec; + +#else + +# include "__concepts.hpp" +# include "__type_traits.hpp" +# include "__typeinfo.hpp" + +# if !STDEXEC_USE_MODULES() +# include +# include +# include +# include +# include +# endif + +# include "__prologue.hpp" namespace STDEXEC { @@ -44,13 +53,13 @@ namespace STDEXEC template concept __mnever = false; -#if STDEXEC_GCC() && STDEXEC_GCC_VERSION < 1300 +# if STDEXEC_GCC() && STDEXEC_GCC_VERSION < 1300 template using __mtypeof = std::remove_const_t; -#else +# else template using __mtypeof = decltype(_Value); -#endif +# endif template struct __mlist; @@ -99,7 +108,7 @@ namespace STDEXEC template using __indices = __iota<_Is...> *; -#if STDEXEC_MSVC() +# if STDEXEC_MSVC() namespace __pack { template @@ -115,7 +124,7 @@ namespace STDEXEC template using __make_indices = decltype(__pack::__mkidx<__make_integer_seq<__pack::__idx, std::size_t, _Np>>); -#elif STDEXEC_HAS_BUILTIN(__make_integer_seq) +# elif STDEXEC_HAS_BUILTIN(__make_integer_seq) namespace __pack { template @@ -124,7 +133,7 @@ namespace STDEXEC template using __make_indices = __make_integer_seq<__pack::__idx, std::size_t, _Np>; -#elif STDEXEC_HAS_BUILTIN(__integer_pack) +# elif STDEXEC_HAS_BUILTIN(__integer_pack) namespace __pack { template @@ -133,7 +142,7 @@ namespace STDEXEC template using __make_indices = decltype(__pack::__make_indices<_Np>); -#else +# else namespace __pack { template > @@ -154,7 +163,7 @@ namespace STDEXEC template using __make_indices = decltype(__pack::__mk_indices<_Np>); -#endif +# endif template using __indices_for = __make_indices; @@ -417,15 +426,15 @@ namespace STDEXEC template