#pragma once #ifdef _WIN32 #define NOMINMAX #endif #include "uv.h" #ifdef _WIN32 #undef THIS #endif #include #include #include #include #include "Support/TypeTraits.h" #include "Support/Logger.h" namespace clice::async { /// The default event loop. extern uv_loop_t* loop; template T& uv_cast(U* u) { assert(u && u->data && "uv_cast: invalid uv handle"); return *static_cast*>(u->data); } #define UV_TYPE_ITER(_, name) || std::is_same_v /// Check if the type `T` is a libuv handle. template constexpr bool is_uv_handle_v = false UV_HANDLE_TYPE_MAP(UV_TYPE_ITER); /// Check if the type `T` is a libuv request. template constexpr bool is_uv_req_v = false UV_REQ_TYPE_MAP(UV_TYPE_ITER); template constexpr bool is_uv_stream_v = std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v; #undef UV_TYPE_ITER template T* uv_cast(U& u) { if constexpr(std::is_same_v) { static_assert(is_uv_handle_v>, "uv_cast: invalid uv handle"); } else if constexpr(std::is_same_v) { static_assert(is_uv_req_v>, "uv_cast: invalid uv request"); } else if constexpr(std::is_same_v) { static_assert(is_uv_stream_v>, "uv_cast: invalid uv stream"); } else { static_assert(dependent_false, "uv_cast: invalid type"); } return reinterpret_cast(&u); } void uv_check_result(const int result, const std::source_location location = std::source_location::current()); template class Task; template using Result = Task>; const std::error_category& category(); void init(); void run(); void stop(); } // namespace clice::async