17 concept HasShrinkToFit = requires(
const T &t) {
22 concept HasSqueeze = requires(
const T &t) {
27 concept HasPushBack = requires(T t, T::value_type value) {
32 concept HasInsert = requires(T t, T::value_type value) {
36 template<
typename OutputVector,
typename InputVector,
typename Converter>
37 auto transform(
const InputVector &input, Converter convert)
40 HasPushBack<OutputVector> || HasInsert<OutputVector>,
41 "OutputVector must support push_back() or insert()");
44 if constexpr (std::ranges::sized_range<InputVector>) {
45 output.reserve(input.size());
47 for (
const auto &value : input) {
48 if constexpr (HasPushBack<OutputVector>) {
49 output.push_back(std::invoke(convert, value));
50 }
else if constexpr (HasInsert<OutputVector>) {
51 output.insert(std::invoke(convert, value));
57 template<
typename OutputVector,
typename InputVector,
typename Converter>
58 auto transform(InputVector &&input, Converter convert)
61 HasPushBack<OutputVector> || HasInsert<OutputVector>,
62 "OutputVector must support push_back() or insert()");
65 if constexpr (std::ranges::sized_range<InputVector>) {
66 output.reserve(input.size());
68 for (
auto it = input.begin(); it != input.end(); ++it) {
69 if constexpr (HasPushBack<OutputVector>) {
70 output.push_back(std::invoke(convert, std::move(*it)));
71 }
else if constexpr (HasInsert<OutputVector>) {
72 output.insert(std::invoke(convert, std::move(*it)));
78 template<
typename OutputVector,
typename InputVector,
typename Converter>
79 auto transformFilter(
const InputVector &input, Converter convert)
81 using OutputValue =
typename OutputVector::value_type;
83 if constexpr (std::ranges::sized_range<InputVector>) {
84 output.reserve(input.size());
86 for (
const auto &value : input) {
87 if (
const std::optional<OutputValue> result = std::invoke(convert, value)) {
88 output.push_back(*result);
91 if constexpr (std::ranges::sized_range<InputVector>) {
92 if constexpr (HasShrinkToFit<OutputVector>) {
93 output.shrink_to_fit();
94 }
else if constexpr (HasSqueeze<OutputVector>) {
102 template<
typename Container,
typename... Args>
103 auto contains(
const Container &container, Args &&...args) ->
bool 105 return std::ranges::find(container, std::forward<Args>(args)...) != std::end(container);
108 template<
typename Container,
typename... Args>
109 auto find(
const Container &container, Args &&...args) -> std::optional<typename Container::value_type>
111 auto it = std::ranges::find(container, std::forward<Args>(args)...);
112 if (it != std::end(container)) {
118 template<
typename Container,
typename... Args>
119 auto removeIf(Container &container, Args &&...args)
121 auto removedRange = std::ranges::remove_if(container, std::forward<Args>(args)...);
122 container.erase(removedRange.begin(), removedRange.end());
125 template<
typename T,
typename Function>
126 auto map(Function mapValue, std::optional<T> &&optValue) -> std::optional<std::invoke_result_t<Function, T &&>>
129 return mapValue(std::move(*optValue));
134 template<
typename T,
typename Function>
135 auto map(Function mapValue,
const std::optional<T> &optValue) -> std::optional<std::invoke_result_t<Function, T &&>>
138 return mapValue(*optValue);
143 template<
typename Out,
typename Function,
typename... InTypes>
144 auto map(Function mapValue, std::variant<InTypes...> &&variant)
147 [&](
auto &&v) -> Out {
148 if constexpr (std::is_invocable_v<Function, decltype(v)>) {
149 return { mapValue(std::move(v)) };
157 template<
typename Out,
typename Function,
typename... InTypes>
158 auto map(Function mapValue,
const std::variant<InTypes...> &variant)
161 [&](
const auto &v) -> Out {
162 if constexpr (std::is_invocable_v<Function, decltype(v)>) {
163 return { mapValue(v) };
171 template<
typename To,
typename From>
172 auto into(std::optional<From> &&value) -> std::optional<To>
175 return To { *value };
180 template<
typename To,
typename From>
181 auto into(
const std::optional<From> &value) -> std::optional<To>
184 return To { *value };
189 template<
typename GreaterVariant,
typename... BaseTypes>
190 auto into(std::variant<BaseTypes...> &&variant)
192 return std::visit([](
auto &&value) -> GreaterVariant {
return value; }, std::move(variant));
195 template<
typename GreaterVariant,
typename... BaseTypes>
196 auto into(
const std::variant<BaseTypes...> &variant)
198 return std::visit([](
const auto &value) -> GreaterVariant {
return value; }, variant);
203 #endif // ALGORITHMS_H Definition: Algorithms.h:14