10#ifndef BOTAN_STL_UTIL_H_
11#define BOTAN_STL_UTIL_H_
13#include <botan/assert.h>
29template <
typename RetT,
typename KeyT,
typename ReducerT>
30RetT
reduce(
const std::vector<KeyT>& keys, RetT acc, ReducerT reducer)
31 requires std::invocable<ReducerT&, RetT, const KeyT&> &&
32 std::convertible_to<std::invoke_result_t<ReducerT&, RetT, const KeyT&>, RetT>
34 for(
const KeyT& key : keys) {
35 acc = reducer(std::move(acc), key);
43template <
typename T,
typename V>
45 for(
const auto& elem : vec) {
53template <
typename T,
typename Pred>
55 auto i = assoc.begin();
56 while(i != assoc.end()) {
65template <
typename... Alts,
typename... Ts>
66constexpr bool holds_any_of(
const std::variant<Ts...>& v)
noexcept {
67 return (std::holds_alternative<Alts>(v) || ...);
70template <
typename GeneralVariantT,
typename SpecialT>
72 return std::is_constructible_v<GeneralVariantT, SpecialT>;
75template <
typename GeneralVariantT,
typename... SpecialTs>
77 return (std::is_constructible_v<GeneralVariantT, SpecialTs> && ...);
87template <
typename GeneralVariantT,
typename SpecialT>
89 requires(std::is_constructible_v<GeneralVariantT, std::decay_t<SpecialT>>)
91 return std::forward<SpecialT>(specific);
101template <
typename GeneralVariantT,
typename... SpecialTs>
102constexpr GeneralVariantT
generalize_to(std::variant<SpecialTs...> specific) {
105 "Desired general type must be implicitly constructible by all types of the specialized std::variant<>");
106 return std::visit([](
auto s) -> GeneralVariantT {
return s; }, std::move(specific));
116template <
typename SpecificVariantT,
typename GeneralVariantT>
117constexpr std::optional<SpecificVariantT>
specialize_to(GeneralVariantT&& v) {
119 []<
typename AlternativeT>(AlternativeT&& obj) -> std::optional<SpecificVariantT> {
120 if constexpr(std::is_constructible_v<SpecificVariantT, AlternativeT>) {
121 return std::forward<AlternativeT>(obj);
126 std::forward<GeneralVariantT>(v));
131template <
class... Ts>
133 using Ts::operator()...;
136template <
class... Ts>
141 requires std::is_enum_v<T>
143 return static_cast<std::underlying_type_t<T>
>(e);
148[[nodiscard]]
constexpr auto out_ptr(T& outptr)
noexcept {
151 constexpr ~out_ptr_t()
noexcept {
152 m_ptr.reset(m_rawptr);
156 constexpr explicit out_ptr_t(T& outptr) noexcept : m_ptr(outptr), m_rawptr(
nullptr) {}
158 out_ptr_t(
const out_ptr_t&) =
delete;
159 out_ptr_t(out_ptr_t&&) =
delete;
160 out_ptr_t& operator=(
const out_ptr_t&) =
delete;
161 out_ptr_t& operator=(out_ptr_t&&) =
delete;
164 [[nodiscard]]
constexpr operator typename T::element_type **() &&
noexcept {
return &m_rawptr; }
168 typename T::element_type* m_rawptr;
171 return out_ptr_t{outptr};
void map_remove_if(Pred pred, T &assoc)
constexpr auto out_ptr(T &outptr) noexcept
auto to_underlying(T e) noexcept
constexpr bool holds_any_of(const std::variant< Ts... > &v) noexcept
constexpr std::optional< SpecificVariantT > specialize_to(GeneralVariantT &&v)
Converts a given variant into another variant whose type states are a subset of the given variant.
bool value_exists(const std::vector< T > &vec, const V &val)
RetT reduce(const std::vector< KeyT > &keys, RetT acc, ReducerT reducer)
constexpr bool is_generalizable_to(const SpecialT &) noexcept
overloaded(Ts...) -> overloaded< Ts... >
constexpr GeneralVariantT generalize_to(SpecialT &&specific)
Converts a given variant into another variant-ish whose type states are a super set of the given vari...