Skip to content

Commit

Permalink
feat utils: publish constexpr_indices.hpp
Browse files Browse the repository at this point in the history
67d1529c81286c3211465acb26b29a5eed28cd21
  • Loading branch information
Anton3 committed Feb 15, 2024
1 parent 5745dfb commit 3db1957
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 11 deletions.
1 change: 1 addition & 0 deletions .mapping.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
16 changes: 5 additions & 11 deletions core/include/userver/dump/common_containers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <variant>
#include <vector>

#include <userver/utils/constexpr_indices.hpp>
#include <userver/utils/lazy_prvalue.hpp>
#include <userver/utils/meta.hpp>
#include <userver/utils/strong_typedef.hpp>
Expand Down Expand Up @@ -71,23 +72,16 @@ auto ReadLazyPrvalue(Reader& reader) {
[[noreturn]] void ThrowInvalidVariantIndex(const std::type_info& type,
std::size_t index);

template <std::size_t... Indices, typename Func>
void ForEachIndex(std::index_sequence<Indices...>, Func func) {
(func(std::integral_constant<std::size_t, Indices>{}), ...);
}

template <typename VariantType>
VariantType ReadVariant(Reader& reader, std::size_t index) {
static constexpr auto VariantSize = std::variant_size_v<VariantType>;
std::optional<VariantType> result;
using Indices = std::make_index_sequence<std::variant_size_v<VariantType>>;

ForEachIndex(Indices{}, [&](auto index_constant) {
utils::WithConstexprIndex<VariantSize>(index, [&](auto index_constant) {
static constexpr auto kIndex = decltype(index_constant)::value;
using Alternative = std::variant_alternative_t<kIndex, VariantType>;
if (index == kIndex) {
// Not using ReadLazyPrvalue because of stdlib issues on some compilers.
result.emplace(std::in_place_index<kIndex>, reader.Read<Alternative>());
}
// Not using ReadLazyPrvalue because of stdlib issues on some compilers.
result.emplace(std::in_place_index<kIndex>, reader.Read<Alternative>());
});

return std::move(*result);
Expand Down
49 changes: 49 additions & 0 deletions universal/include/userver/utils/constexpr_indices.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#pragma once

/// @file userver/utils/constexpr_indices.hpp
/// @brief Functions for iterating over a constexpr range of integers

#include <cstddef>
#include <type_traits>
#include <utility>

USERVER_NAMESPACE_BEGIN

namespace utils {

namespace impl {

template <std::size_t... Indices, typename Func>
void DoForEachIndex(std::index_sequence<Indices...>, Func func) {
static_assert(std::is_trivially_copyable_v<Func>);
(..., func(std::integral_constant<std::size_t, Indices>{}));
}

template <std::size_t... Indices, typename Func>
void DoWithConstexprIndex(std::index_sequence<Indices...>,
std::size_t runtime_index, Func func) {
static_assert(std::is_trivially_copyable_v<Func>);
(..., (runtime_index == Indices
? func(std::integral_constant<std::size_t, Indices>{})
: void()));
}

} // namespace impl

/// Calls `func` with indices from range `0...<Count`, wrapped in
/// `std::integral_constant`.
template <std::size_t Count, typename Func>
void ForEachIndex(Func func) {
impl::DoForEachIndex(std::make_index_sequence<Count>{}, func);
}

/// Calls `func` with `runtime_index` wrapped in `std::integral_constant`.
template <std::size_t Count, typename Func>
void WithConstexprIndex(std::size_t runtime_index, Func func) {
impl::DoWithConstexprIndex(std::make_index_sequence<Count>{}, runtime_index,
func);
}

} // namespace utils

USERVER_NAMESPACE_END

0 comments on commit 3db1957

Please sign in to comment.