diff --git a/.mapping.json b/.mapping.json index 4395f333272d..e1a1246209f5 100644 --- a/.mapping.json +++ b/.mapping.json @@ -3200,6 +3200,7 @@ "universal/include/userver/utils/bytes_per_second.hpp":"taxi/uservices/userver/universal/include/userver/utils/bytes_per_second.hpp", "universal/include/userver/utils/cached_hash.hpp":"taxi/uservices/userver/universal/include/userver/utils/cached_hash.hpp", "universal/include/userver/utils/checked_pointer.hpp":"taxi/uservices/userver/universal/include/userver/utils/checked_pointer.hpp", + "universal/include/userver/utils/constexpr_indices.hpp":"taxi/uservices/userver/universal/include/userver/utils/constexpr_indices.hpp", "universal/include/userver/utils/datetime.hpp":"taxi/uservices/userver/universal/include/userver/utils/datetime.hpp", "universal/include/userver/utils/datetime/cpp_20_calendar.hpp":"taxi/uservices/userver/universal/include/userver/utils/datetime/cpp_20_calendar.hpp", "universal/include/userver/utils/datetime/date.hpp":"taxi/uservices/userver/universal/include/userver/utils/datetime/date.hpp", diff --git a/core/include/userver/dump/common_containers.hpp b/core/include/userver/dump/common_containers.hpp index 5db30b6a1bf5..32c1b6be9785 100644 --- a/core/include/userver/dump/common_containers.hpp +++ b/core/include/userver/dump/common_containers.hpp @@ -24,6 +24,7 @@ #include #include +#include #include #include #include @@ -71,23 +72,16 @@ auto ReadLazyPrvalue(Reader& reader) { [[noreturn]] void ThrowInvalidVariantIndex(const std::type_info& type, std::size_t index); -template -void ForEachIndex(std::index_sequence, Func func) { - (func(std::integral_constant{}), ...); -} - template VariantType ReadVariant(Reader& reader, std::size_t index) { + static constexpr auto VariantSize = std::variant_size_v; std::optional result; - using Indices = std::make_index_sequence>; - ForEachIndex(Indices{}, [&](auto index_constant) { + utils::WithConstexprIndex(index, [&](auto index_constant) { static constexpr auto kIndex = decltype(index_constant)::value; using Alternative = std::variant_alternative_t; - if (index == kIndex) { - // Not using ReadLazyPrvalue because of stdlib issues on some compilers. - result.emplace(std::in_place_index, reader.Read()); - } + // Not using ReadLazyPrvalue because of stdlib issues on some compilers. + result.emplace(std::in_place_index, reader.Read()); }); return std::move(*result); diff --git a/universal/include/userver/utils/constexpr_indices.hpp b/universal/include/userver/utils/constexpr_indices.hpp new file mode 100644 index 000000000000..0ea17854c535 --- /dev/null +++ b/universal/include/userver/utils/constexpr_indices.hpp @@ -0,0 +1,49 @@ +#pragma once + +/// @file userver/utils/constexpr_indices.hpp +/// @brief Functions for iterating over a constexpr range of integers + +#include +#include +#include + +USERVER_NAMESPACE_BEGIN + +namespace utils { + +namespace impl { + +template +void DoForEachIndex(std::index_sequence, Func func) { + static_assert(std::is_trivially_copyable_v); + (..., func(std::integral_constant{})); +} + +template +void DoWithConstexprIndex(std::index_sequence, + std::size_t runtime_index, Func func) { + static_assert(std::is_trivially_copyable_v); + (..., (runtime_index == Indices + ? func(std::integral_constant{}) + : void())); +} + +} // namespace impl + +/// Calls `func` with indices from range `0... +void ForEachIndex(Func func) { + impl::DoForEachIndex(std::make_index_sequence{}, func); +} + +/// Calls `func` with `runtime_index` wrapped in `std::integral_constant`. +template +void WithConstexprIndex(std::size_t runtime_index, Func func) { + impl::DoWithConstexprIndex(std::make_index_sequence{}, runtime_index, + func); +} + +} // namespace utils + +USERVER_NAMESPACE_END