16#include <userver/utils/checked_pointer.hpp>
18USERVER_NAMESPACE_BEGIN
23template <
typename ResultString = std::string,
typename... Strings>
24ResultString
StrCat(
const Strings&... strings) {
25 return [](
auto... string_views) {
26 std::size_t result_size = 0;
27 ((result_size += string_views.size()), ...);
30 result.reserve(result_size);
31 (result.append(string_views), ...);
33 }(std::string_view{strings}...);
37template <
typename Container,
typename =
void>
38struct HasMappedType : std::false_type {};
40template <
typename Container>
41struct HasMappedType<Container, std::void_t<
typename Container::mapped_type>> : std::true_type {};
43template <
typename Container>
44inline constexpr bool kHasMappedType = HasMappedType<Container>::value;
49template <
typename Container,
typename Key>
51 const auto it = container.find(key);
52 if constexpr (impl::kHasMappedType<Container>) {
53 return (it != container.end() ? &(it->second) :
nullptr);
55 return (it != container.end() ? &(*it) :
nullptr);
61template <
typename Container,
typename Key,
typename Default>
62auto FindOrDefault(Container& container,
const Key& key, Default&& def) {
63 const auto* ptr = USERVER_NAMESPACE::
utils::FindOrNullptr(container, key);
64 return (ptr ? *ptr :
decltype(*ptr){std::forward<Default>(def)});
69template <
typename Container,
typename Key>
71 const auto* ptr = USERVER_NAMESPACE::
utils::FindOrNullptr(container, key);
72 return (ptr ? *ptr :
decltype(*ptr){});
77template <
typename Container,
typename Key>
79 const auto* ptr = USERVER_NAMESPACE::
utils::FindOrNullptr(container, key);
80 return (ptr ? std::make_optional(*ptr) : std::nullopt);
85template <
typename Container,
typename Key>
87 return utils::MakeCheckedPtr(USERVER_NAMESPACE::
utils::FindOrNullptr(container, key));
91template <
typename ToContainer,
typename FromContainer>
93 if constexpr (std::is_rvalue_reference_v<
decltype(container)>) {
95 std::make_move_iterator(std::begin(container)), std::make_move_iterator(std::end(container))
98 return ToContainer(std::begin(container), std::end(container));
103template <
typename Container,
typename =
void>
104struct HasKeyType : std::false_type {};
106template <
typename Container>
107struct HasKeyType<Container, std::void_t<
typename Container::key_type>> : std::true_type {};
109template <
typename Container>
110inline constexpr bool kHasKeyType = HasKeyType<Container>::value;
114template <
typename Container,
typename Pred>
115auto EraseIf(Container& container, Pred pred) {
116 if constexpr (impl::kHasKeyType<Container>) {
117 auto old_size = container.size();
118 for (
auto it = std::begin(container), last = std::end(container); it != last;) {
120 it = container.erase(it);
125 return old_size - container.size();
127 auto it = std::remove_if(std::begin(container), std::end(container), pred);
128 const auto removed = std::distance(it, std::end(container));
129 container.erase(it, std::end(container));
135template <
typename Container,
typename T>
136size_t
Erase(Container& container,
const T& elem) {
137 if constexpr (impl::kHasKeyType<Container>) {
138 return container.erase(elem);
141 auto it = std::remove(std::begin(container), std::end(container), elem);
142 const auto removed = std::distance(it, std::end(container));
143 container.erase(it, std::end(container));
150template <
typename Container,
typename Pred>
152 return std::find_if(std::begin(container), std::end(container), pred) != std::end(container);