diff --git a/runtime-light/coroutine/detail/when-any.h b/runtime-light/coroutine/detail/when-any.h index 085c1f3200..f124f5928e 100644 --- a/runtime-light/coroutine/detail/when-any.h +++ b/runtime-light/coroutine/detail/when-any.h @@ -15,6 +15,7 @@ #include "runtime-light/coroutine/concepts.h" #include "runtime-light/coroutine/type-traits.h" #include "runtime-light/coroutine/void-value.h" +#include "runtime-light/metaprogramming/type-functions.h" #include "runtime-light/stdlib/diagnostics/logs.h" namespace kphp::coro::detail::when_any { @@ -120,7 +121,10 @@ class when_any_ready_awaitable> { const auto task_result_processor{[&result = m_awaitable.m_result](auto&& task) noexcept { if (auto task_result{std::forward(task).result()}; !result.has_value() && task_result.has_value()) { - result = std::move(task_result); + using result_variant_type = std::remove_cvref::type::value_type; + using task_result_type = decltype(task_result)::value_type; + result = + result_variant_type{std::in_place_index()>, *std::move(task_result)}; } }}; std::apply([&task_result_processor](auto&&... tasks) noexcept { (std::invoke(task_result_processor, std::forward(tasks)), ...); }, @@ -290,8 +294,11 @@ class when_any_task { template auto make_when_any_task(awaitable_type awaitable) noexcept -> when_any_task::awaiter_return_type> { - co_yield co_await std::move(awaitable); - co_return; + if constexpr (std::is_void_v::awaiter_return_type>) { + co_await std::move(awaitable); + } else { + co_yield co_await std::move(awaitable); + } } } // namespace kphp::coro::detail::when_any diff --git a/runtime-light/coroutine/io-scheduler.h b/runtime-light/coroutine/io-scheduler.h index 241c518014..657dae1539 100644 --- a/runtime-light/coroutine/io-scheduler.h +++ b/runtime-light/coroutine/io-scheduler.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -463,13 +464,24 @@ auto io_scheduler::schedule(coroutine_type coroutine, std::chrono::duration::return_type; if (timeout <= std::chrono::duration{0}) [[unlikely]] { - co_return std::expected{co_await schedule(std::move(coroutine))}; + if constexpr (std::is_void_v) { + co_await schedule(std::move(coroutine)); + co_return std::expected{}; + } else { + co_return std::expected{co_await schedule(std::move(coroutine))}; + } } + auto result{co_await kphp::coro::when_any(std::move(coroutine), make_timeout_task(timeout))}; if (std::holds_alternative(result)) [[unlikely]] { co_return std::unexpected{std::move(std::get<1>(result))}; } - co_return std::expected{std::move(std::get<0>(result))}; + + if constexpr (std::is_void_v) { + co_return std::expected{}; + } else { + co_return std::expected{std::move(std::get<0>(result))}; + } } template diff --git a/runtime-light/utils/concepts.h b/runtime-light/metaprogramming/concepts.h similarity index 89% rename from runtime-light/utils/concepts.h rename to runtime-light/metaprogramming/concepts.h index a2db5a90fe..0912acd607 100644 --- a/runtime-light/utils/concepts.h +++ b/runtime-light/metaprogramming/concepts.h @@ -8,6 +8,8 @@ #include #include +namespace kphp::concepts { + template concept standard_layout = std::is_standard_layout_v; @@ -18,3 +20,5 @@ concept hashable = requires(T t) { template concept in_types = (std::same_as || ...); + +} // namespace kphp::concepts diff --git a/runtime-light/metaprogramming/type-functions.h b/runtime-light/metaprogramming/type-functions.h new file mode 100644 index 0000000000..350fa453d7 --- /dev/null +++ b/runtime-light/metaprogramming/type-functions.h @@ -0,0 +1,23 @@ +// Compiler for PHP (aka KPHP) +// Copyright (c) 2025 LLC «V Kontakte» +// Distributed under the GPL v3 License, see LICENSE.notice.txt + +#pragma once + +#include +#include +#include + +namespace kphp::type_functions { + +template +requires(index < std::variant_size_v) +consteval size_t variant_index() noexcept { + if constexpr (std::is_same_v, T>) { + return index; + } else { + return variant_index(); + } +} + +} // namespace kphp::type_functions diff --git a/runtime-light/runtime-light.cmake b/runtime-light/runtime-light.cmake index 3cc64e6e03..cbb74d4d38 100644 --- a/runtime-light/runtime-light.cmake +++ b/runtime-light/runtime-light.cmake @@ -22,7 +22,6 @@ include(${RUNTIME_LIGHT_DIR}/coroutine/coroutine.cmake) include(${RUNTIME_LIGHT_DIR}/server/server.cmake) include(${RUNTIME_LIGHT_DIR}/stdlib/stdlib.cmake) include(${RUNTIME_LIGHT_DIR}/tl/tl.cmake) -include(${RUNTIME_LIGHT_DIR}/utils/utils.cmake) include(${RUNTIME_LIGHT_DIR}/state/state.cmake) include(${RUNTIME_LIGHT_DIR}/memory-resource-impl/memory-resource-impl.cmake) diff --git a/runtime-light/utils/php-assert.cpp b/runtime-light/stdlib/diagnostics/php-assert.cpp similarity index 100% rename from runtime-light/utils/php-assert.cpp rename to runtime-light/stdlib/diagnostics/php-assert.cpp diff --git a/runtime-light/utils/null_coalesce.h b/runtime-light/stdlib/operators/null_coalesce.h similarity index 100% rename from runtime-light/utils/null_coalesce.h rename to runtime-light/stdlib/operators/null_coalesce.h diff --git a/runtime-light/stdlib/stdlib.cmake b/runtime-light/stdlib/stdlib.cmake index a176dac8f5..22ceaece1f 100644 --- a/runtime-light/stdlib/stdlib.cmake +++ b/runtime-light/stdlib/stdlib.cmake @@ -8,6 +8,7 @@ prepend( diagnostics/backtrace.cpp diagnostics/contextual-logger.cpp diagnostics/error-handling-state.cpp + diagnostics/php-assert.cpp file/resource.cpp fork/fork-state.cpp fork/wait-queue-state.cpp diff --git a/runtime-light/stdlib/string/regex-state.h b/runtime-light/stdlib/string/regex-state.h index d7ebee625d..6d6fb64b1e 100644 --- a/runtime-light/stdlib/string/regex-state.h +++ b/runtime-light/stdlib/string/regex-state.h @@ -10,11 +10,11 @@ #include "common/mixin/not_copyable.h" #include "runtime-common/core/allocator/script-allocator.h" #include "runtime-common/core/std/containers.h" +#include "runtime-light/metaprogramming/concepts.h" #include "runtime-light/stdlib/string/regex-include.h" -#include "runtime-light/utils/concepts.h" struct RegexInstanceState final : private vk::not_copyable { - template + template using unordered_map = kphp::stl::unordered_map; static constexpr size_t MAX_SUBPATTERNS_COUNT = 512; diff --git a/runtime-light/tl/tl-core.h b/runtime-light/tl/tl-core.h index 9c9d378d28..6be470c403 100644 --- a/runtime-light/tl/tl-core.h +++ b/runtime-light/tl/tl-core.h @@ -15,8 +15,8 @@ #include "common/algorithms/find.h" #include "runtime-common/core/allocator/script-allocator.h" #include "runtime-common/core/std/containers.h" +#include "runtime-light/metaprogramming/concepts.h" #include "runtime-light/stdlib/diagnostics/logs.h" -#include "runtime-light/utils/concepts.h" namespace tl { @@ -66,7 +66,7 @@ class storer { m_buffer.append_range(bytes); } - template + template requires std::convertible_to void store_trivial(const U& t) noexcept { store_bytes({reinterpret_cast(std::addressof(t)), sizeof(T)}); @@ -136,7 +136,7 @@ class fetcher { return bytes; } - template + template std::optional fetch_trivial() noexcept { if (m_remaining < sizeof(T)) { return std::nullopt; diff --git a/runtime-light/utils/utils.cmake b/runtime-light/utils/utils.cmake deleted file mode 100644 index 911086ea12..0000000000 --- a/runtime-light/utils/utils.cmake +++ /dev/null @@ -1 +0,0 @@ -prepend(RUNTIME_LIGHT_UTILS_SRC utils/ php-assert.cpp)