diff --git a/CMakeLists.txt b/CMakeLists.txt index cfde06a..48b6624 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,7 @@ set(ASYNCIO_VERSION 1.1.0) option(BUILD_SAMPLES "Build asyncio samples" ON) option(BUILD_SHARED_LIBS "Build using shared libraries" OFF) +option(BUILD_MODULES "Build asyncio modules" OFF) option(ASYNCIO_EMBED_CA_CERT "Use built-in CA certificates instead of system certificates" OFF) if (BUILD_SHARED_LIBS AND MSVC) @@ -76,10 +77,10 @@ if (WIN32) endif () target_include_directories( - asyncio - PUBLIC - $ - $ + asyncio + PUBLIC + $ + $ ) target_link_libraries( @@ -100,49 +101,49 @@ add_library(asyncio-main STATIC src/main.cpp) target_link_libraries(asyncio-main PUBLIC asyncio) install( - DIRECTORY - include/ - DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} - ${EXCLUDE_HEADERS} + DIRECTORY + include/ + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} + ${EXCLUDE_HEADERS} ) install( - TARGETS asyncio - EXPORT ${PROJECT_NAME}Targets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} - LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} - RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + TARGETS asyncio + EXPORT ${PROJECT_NAME}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} ) install( - TARGETS asyncio-main - EXPORT ${PROJECT_NAME}Targets - ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + TARGETS asyncio-main + EXPORT ${PROJECT_NAME}Targets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install( - EXPORT ${PROJECT_NAME}Targets - NAMESPACE ${PROJECT_NAME}:: - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + EXPORT ${PROJECT_NAME}Targets + NAMESPACE ${PROJECT_NAME}:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) configure_package_config_file( - cmake/${PROJECT_NAME}-config.cmake.in - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + cmake/${PROJECT_NAME}-config.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) write_basic_package_version_file( - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - VERSION ${ASYNCIO_VERSION} - COMPATIBILITY SameMajorVersion + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + VERSION ${ASYNCIO_VERSION} + COMPATIBILITY SameMajorVersion ) install( - FILES - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake - ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake - DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} + FILES + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake + ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME} ) if (BUILD_SAMPLES) @@ -152,3 +153,7 @@ endif () if (BUILD_TESTING) add_subdirectory(test) endif () + +if (BUILD_MODULES) + add_subdirectory(modules) +endif () diff --git a/README.md b/README.md index c304ea4..24cf282 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,7 @@ Based on the `libuv` event loop, use C++20 stackless `coroutines` to implement n - Multiple sub-task aggregation methods with structured concurrency model, inspired by JavaScript's `Promise`. - Flexible dynamic task management solution, similar to Golang's `WaitGroup`. - Built-in call stack tracing that can traverse the task tree top-down or complete backtracing bottom-up. +- Support for C++20 modules.

(back to top)

diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt new file mode 100644 index 0000000..bce9e19 --- /dev/null +++ b/modules/CMakeLists.txt @@ -0,0 +1,29 @@ + +add_library(asyncio_module) + +target_sources(asyncio_module + PUBLIC + FILE_SET CXX_MODULES FILES + asyncio.cppm + asyncio.http.cppm + asyncio.net.cppm + asyncio.sync.cppm +) + +target_compile_features(asyncio_module PUBLIC cxx_std_20) + +target_include_directories(asyncio_module PUBLIC + $ + $ +) + +add_library(asyncio::module ALIAS asyncio_module) + +# Installation +install(TARGETS asyncio_module + EXPORT ${PROJECT_NAME}Targets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + FILE_SET CXX_MODULES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/asyncio/modules +) \ No newline at end of file diff --git a/modules/asyncio.cppm b/modules/asyncio.cppm new file mode 100644 index 0000000..03bdf4b --- /dev/null +++ b/modules/asyncio.cppm @@ -0,0 +1,197 @@ +module; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +export module asyncio; + +export import :http; +export import :net; +export import :sync; + +export namespace asyncio { + namespace binary { + using asyncio::binary::readLE; + using asyncio::binary::readBE; + using asyncio::binary::writeLE; + using asyncio::binary::writeBE; + } + + using asyncio::BufReader; + using asyncio::BufWriter; + using asyncio::BufReaderError; + + using asyncio::ChannelCore; + using asyncio::Sender; + using asyncio::Receiver; + using asyncio::Channel; + using asyncio::channel; + using asyncio::TrySendError; + using asyncio::SendSyncError; + using asyncio::SendError; + using asyncio::TryReceiveError; + using asyncio::ReceiveSyncError; + using asyncio::ReceiveError; + using asyncio::ChannelError; + + using asyncio::EventLoop; + using asyncio::run; + using asyncio::reschedule; + + using asyncio::File; + using asyncio::open; + using asyncio::read; + using asyncio::readString; + using asyncio::write; + using asyncio::absolute; + using asyncio::canonical; + using asyncio::weaklyCanonical; + using asyncio::relative; + using asyncio::proximate; + using asyncio::copy; + using asyncio::copyFile; + using asyncio::copySymlink; + using asyncio::createDirectory; + using asyncio::createDirectories; + using asyncio::createHardLink; + using asyncio::createSymlink; + using asyncio::createDirectorySymlink; + using asyncio::currentPath; + using asyncio::exists; + using asyncio::equivalent; + using asyncio::fileSize; + using asyncio::hardLinkCount; + using asyncio::lastWriteTime; + using asyncio::permissions; + using asyncio::readSymlink; + using asyncio::remove; + using asyncio::removeAll; + using asyncio::rename; + using asyncio::resizeFile; + using asyncio::space; + using asyncio::status; + using asyncio::symlinkStatus; + using asyncio::temporaryDirectory; + using asyncio::isBlockFile; + using asyncio::isCharacterFile; + using asyncio::isDirectory; + using asyncio::isEmpty; + using asyncio::isFIFO; + using asyncio::isOther; + using asyncio::isRegularFile; + using asyncio::isSocket; + using asyncio::isSymlink; + using asyncio::DirectoryEntry; + using asyncio::Asynchronous; + using asyncio::readDirectory; + using asyncio::walkDirectory; + + using asyncio::FileDescriptor; + using asyncio::IFileDescriptor; + using asyncio::ICloseable; + using asyncio::IHalfCloseable; + using asyncio::IReader; + using asyncio::IWriter; + using asyncio::ISeekable; + using asyncio::IBufReader; + using asyncio::IBufWriter; + using asyncio::copy; + using asyncio::StringReader; + using asyncio::StringWriter; + using asyncio::BytesReader; + using asyncio::BytesWriter; + using asyncio::IOError; + + using asyncio::Pipe; + using asyncio::PipeListener; + + using asyncio::Poll; + + using asyncio::Process; + using asyncio::ExitStatus; + using asyncio::Output; + using asyncio::ChildProcess; + using asyncio::Command; + using asyncio::PseudoConsole; + + using asyncio::Promise; + + using asyncio::Signal; + + using asyncio::Stream; + using asyncio::Listener; + + namespace task { + using asyncio::task::Awaitable; + using asyncio::task::NoExceptAwaitable; + using asyncio::task::TaskGroup; + using asyncio::task::Frame; + using asyncio::task::CancellableFuture; + using asyncio::task::CancellableTask; + using asyncio::task::Cancelled; + using asyncio::task::Lock; + using asyncio::task::Unlock; + using asyncio::task::cancelled; + using asyncio::task::lock; + using asyncio::task::unlock; + using asyncio::task::callback_result_t; + using asyncio::task::Task; + using asyncio::task::Promise; + using asyncio::task::all_ranges_future_t; + using asyncio::task::all_ranges_value_t; + using asyncio::task::all_ranges_error_t; + using asyncio::task::all; + using asyncio::task::all_varaidic_future_t; + using asyncio::task::all_variadic_value_t; + using asyncio::task::all_variadic_error_t; + using asyncio::task::all_settled_ranges_future_t; + using asyncio::task::all_settled_ranges_value_t; + using asyncio::task::allSettled; + using asyncio::task::all_settled_variadic_future_t; + using asyncio::task::all_settled_variadic_value_t; + using asyncio::task::any_ranges_future_t; + using asyncio::task::any_ranges_value_t; + using asyncio::task::any_ranges_error_t; + using asyncio::task::any; + using asyncio::task::any_variadic_future_t; + using asyncio::task::any_variadic_value_t; + using asyncio::task::any_variadic_error_t; + using asyncio::task::race_ranges_future_t; + using asyncio::task::race_ranges_value_t; + using asyncio::task::race_ranges_error_t; + using asyncio::task::race; + using asyncio::task::race_variadic_future_t; + using asyncio::task::race_variadic_value_t; + using asyncio::task::race_variadic_error_t; + using asyncio::task::from; + using asyncio::task::spawn; + using asyncio::task::Error; + } + + using asyncio::toThread; + using asyncio::toThreadPool; + using asyncio::ToThreadPoolError; + + using asyncio::timeout; + using asyncio::TimeoutError; + + namespace uv { + using asyncio::uv::expected; + using asyncio::uv::Handle; + using asyncio::uv::Error; + } +} diff --git a/modules/asyncio.http.cppm b/modules/asyncio.http.cppm new file mode 100644 index 0000000..07c4d44 --- /dev/null +++ b/modules/asyncio.http.cppm @@ -0,0 +1,47 @@ +module; + +#include +#include +#include + +export module asyncio:http; + +export namespace asyncio::http { + using asyncio::http::Connection; + using asyncio::http::Requests; + using asyncio::http::Response; + using asyncio::http::TLSConfig; + using asyncio::http::Options; + using asyncio::http::CURLError; + using asyncio::http::CURLMError; + + using asyncio::http::urlEscape; + using asyncio::http::urlUnescape; + using asyncio::http::URL; + using asyncio::http::operator<=>; + using asyncio::http::operator==; + + namespace ws { + using asyncio::http::ws::CloseCode; + using asyncio::http::ws::CloseCodeCategory; + using asyncio::http::ws::make_error_code; + using asyncio::http::ws::Opcode; + using asyncio::http::ws::InternalMessage; + using asyncio::http::ws::Message; + using asyncio::http::ws::Header; + using asyncio::http::ws::Frame; + using asyncio::http::ws::Compressor; + using asyncio::http::ws::Decompressor; + using asyncio::http::ws::DeflateConfig; + using asyncio::http::ws::DeflateExtension; + using asyncio::http::ws::WebSocket; + } +} + +export namespace zero { + using zero::scan; +} + +export namespace fmt { + using fmt::formatter; +} diff --git a/modules/asyncio.net.cppm b/modules/asyncio.net.cppm new file mode 100644 index 0000000..67ec927 --- /dev/null +++ b/modules/asyncio.net.cppm @@ -0,0 +1,74 @@ +module; + +#include +#include +#include +#include +#include + +export module asyncio:net; + +export namespace asyncio::net { + using asyncio::net::UDPSocket; + + using asyncio::net::getAddressInfo; + using asyncio::net::lookupIP; + + using asyncio::net::IPv4; + using asyncio::net::IPv6; + using asyncio::net::IP; + using asyncio::net::LOCALHOST_IPV4; + using asyncio::net::BROADCAST_IPV4; + using asyncio::net::UNSPECIFIED_IPV4; + using asyncio::net::LOCALHOST_IPV6; + using asyncio::net::UNSPECIFIED_IPV6; + using asyncio::net::IPv4Address; + using asyncio::net::IPv6Address; + using asyncio::net::UnixAddress; + using asyncio::net::IPAddress; + using asyncio::net::Address; + using asyncio::net::SocketAddress; + using asyncio::net::operator==; + using asyncio::net::ipAddressFrom; + using asyncio::net::addressFrom; + using asyncio::net::socketAddressFrom; + using asyncio::net::IEndpoint; + using asyncio::net::ISocket; + using asyncio::net::copyBidirectional; + using asyncio::net::ParseAddressError; + + using asyncio::net::TCPStream; + using asyncio::net::TCPListener; + #ifdef _WIN32 + using asyncio::net::NamedPipeStream; + using asyncio::net::NamedPipeListener; + #else + using asyncio::net::UnixStream; + using asyncio::net::UnixListener; + #endif + + namespace tls { + using asyncio::net::tls::openSSLError; + #ifdef __linux__ + using asyncio::net::tls::systemCABundle; + #endif + using asyncio::net::tls::expected; + using asyncio::net::tls::Version; + using asyncio::net::tls::Certificate; + using asyncio::net::tls::PrivateKey; + using asyncio::net::tls::CertKeyPair; + using asyncio::net::tls::Context; + using asyncio::net::tls::ClientConfig; + using asyncio::net::tls::ServerConfig; + using asyncio::net::tls::Config; + using asyncio::net::tls::TLS; + using asyncio::net::tls::connect; + using asyncio::net::tls::accept; + using asyncio::net::tls::OpenSSLError; + using asyncio::net::tls::TLSError; + } +} + +export namespace fmt { + using fmt::formatter; +} diff --git a/modules/asyncio.sync.cppm b/modules/asyncio.sync.cppm new file mode 100644 index 0000000..710bfbb --- /dev/null +++ b/modules/asyncio.sync.cppm @@ -0,0 +1,15 @@ +module; + +#include +#include +#include + +export module asyncio:sync; + +export namespace asyncio::sync { + using asyncio::sync::Condition; + + using asyncio::sync::Event; + + using asyncio::sync::Mutex; +}