2022-10-15 14:44:35 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <Geode/DefaultInclude.hpp>
|
|
|
|
#include <string>
|
|
|
|
#include <algorithm>
|
|
|
|
|
|
|
|
namespace geode::utils::ranges {
|
|
|
|
template<class C>
|
|
|
|
concept ValidConstContainer = requires(C const& c) {
|
|
|
|
c.begin();
|
|
|
|
c.end();
|
2022-10-25 14:49:50 -04:00
|
|
|
{ c.size() } -> std::convertible_to<size_t>;
|
2022-10-15 14:44:35 -04:00
|
|
|
typename C::value_type;
|
2022-10-24 04:43:17 -04:00
|
|
|
typename C::iterator;
|
|
|
|
typename C::const_iterator;
|
2022-10-15 14:44:35 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
template<class C>
|
|
|
|
concept ValidMutContainer = requires(C& c) {
|
|
|
|
c.begin();
|
|
|
|
c.end();
|
2022-10-25 14:49:50 -04:00
|
|
|
{ c.size() } -> std::convertible_to<size_t>;
|
2022-10-15 14:44:35 -04:00
|
|
|
typename C::value_type;
|
2022-10-24 04:43:17 -04:00
|
|
|
typename C::iterator;
|
|
|
|
typename C::const_iterator;
|
2022-10-15 14:44:35 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
template<class C>
|
|
|
|
concept ValidContainer = ValidConstContainer<C> && ValidMutContainer<C>;
|
|
|
|
|
|
|
|
template<class P, class C>
|
|
|
|
concept ValidCUnaryPredicate = requires(P p, typename C::value_type const& t) {
|
|
|
|
{ p(t) } -> std::convertible_to<bool>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<class P, class From, class Into>
|
|
|
|
concept ValidIntoConverter = requires(P p, From const& t) {
|
|
|
|
{ p(t) } -> std::convertible_to<Into>;
|
|
|
|
};
|
|
|
|
|
|
|
|
template<ValidConstContainer C>
|
|
|
|
bool contains(C const& cont, typename C::value_type const& elem) {
|
|
|
|
return std::find(cont.begin(), cont.end(), elem) != cont.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidConstContainer C, ValidCUnaryPredicate<C> Predicate>
|
|
|
|
bool contains(C const& cont, Predicate fun) {
|
|
|
|
return std::find_if(cont.begin(), cont.end(), fun) != cont.end();
|
|
|
|
}
|
|
|
|
|
2022-10-24 04:43:17 -04:00
|
|
|
template<ValidConstContainer C, ValidCUnaryPredicate<C> Predicate>
|
|
|
|
std::optional<typename C::value_type> find(C const& cont, Predicate fun) {
|
|
|
|
auto it = std::find_if(cont.begin(), cont.end(), fun);
|
|
|
|
if (it != cont.end()) {
|
|
|
|
return std::optional(*it);
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
2022-10-25 14:49:50 -04:00
|
|
|
template<ValidConstContainer C>
|
|
|
|
std::optional<size_t> indexOf(C const& cont, typename C::value_type const& elem) {
|
2022-10-24 04:43:17 -04:00
|
|
|
auto it = std::find(cont.begin(), cont.end(), elem);
|
|
|
|
if (it != cont.end()) {
|
2022-10-25 14:49:50 -04:00
|
|
|
return std::optional(std::distance(cont.begin(), it));
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidConstContainer C, ValidCUnaryPredicate<C> Predicate>
|
|
|
|
std::optional<size_t> indexOf(C const& cont, Predicate fun) {
|
|
|
|
auto it = std::find_if(cont.begin(), cont.end(), fun);
|
|
|
|
if (it != cont.end()) {
|
|
|
|
return std::optional(std::distance(cont.begin(), it));
|
|
|
|
}
|
|
|
|
return std::nullopt;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidMutContainer C>
|
|
|
|
bool move(C& cont, typename C::value_type const& elem, size_t where) {
|
|
|
|
if (where > cont.size() - 1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
auto ix = indexOf(cont, elem);
|
|
|
|
if (ix) {
|
|
|
|
if (ix.value() > where) {
|
|
|
|
std::rotate(
|
|
|
|
cont.rend() - ix.value() - 1,
|
|
|
|
cont.rend() - ix.value(),
|
|
|
|
cont.rend() - where
|
|
|
|
);
|
|
|
|
} else {
|
|
|
|
std::rotate(
|
|
|
|
cont.begin() + ix.value(),
|
|
|
|
cont.begin() + ix.value() + 1,
|
|
|
|
cont.begin() + where + 1
|
|
|
|
);
|
|
|
|
}
|
2022-10-24 04:43:17 -04:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-10-15 14:44:35 -04:00
|
|
|
template<ValidConstContainer C, class Output>
|
|
|
|
requires
|
|
|
|
std::is_default_constructible_v<Output> &&
|
|
|
|
std::is_convertible_v<Output, typename C::value_type>
|
|
|
|
Output join(C const& cont, Output const& separator) {
|
|
|
|
auto res = Output();
|
|
|
|
bool first = true;
|
|
|
|
for (auto& p : cont) {
|
|
|
|
if (!first) {
|
|
|
|
res += separator;
|
|
|
|
} else {
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
res += p;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidConstContainer C>
|
|
|
|
std::string join(C const& cont, std::string const& separator) {
|
|
|
|
auto res = std::string();
|
|
|
|
bool first = true;
|
|
|
|
for (auto& p : cont) {
|
|
|
|
if (!first) {
|
|
|
|
res += separator;
|
|
|
|
} else {
|
|
|
|
first = false;
|
|
|
|
}
|
|
|
|
res += p;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<
|
|
|
|
ValidConstContainer C,
|
|
|
|
class Output,
|
|
|
|
ValidIntoConverter<typename C::value_type, Output> Conv
|
|
|
|
>
|
|
|
|
requires
|
|
|
|
std::is_default_constructible_v<Output>
|
|
|
|
Output join(C const& cont, Output const& separator, Conv converter) {
|
|
|
|
auto res = Output();
|
|
|
|
bool first = true;
|
|
|
|
for (auto& p : cont) {
|
|
|
|
if (!first) {
|
|
|
|
res += separator;
|
|
|
|
} else {
|
|
|
|
first = false;
|
|
|
|
}
|
2022-10-24 15:46:39 -04:00
|
|
|
res += converter(p);
|
2022-10-15 14:44:35 -04:00
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidContainer C>
|
|
|
|
C& push(C& container, C const& toAdd) {
|
|
|
|
container.insert(container.end(), toAdd.begin(), toAdd.end());
|
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidMutContainer C>
|
|
|
|
C& remove(C& container, typename C::value_type const& value) {
|
|
|
|
container.erase(
|
|
|
|
std::remove(container.begin(), container.end(), value),
|
|
|
|
container.end()
|
|
|
|
);
|
|
|
|
return container;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<ValidContainer C, ValidCUnaryPredicate<C> Predicate>
|
|
|
|
C filter(C const& container, Predicate filterFun) {
|
|
|
|
auto res = C();
|
|
|
|
std::copy_if(container.begin(), container.end(), res.end(), filterFun);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class R, ValidConstContainer C, class Reducer>
|
|
|
|
requires requires(Reducer r, R& acc, typename C::value_type t) {
|
2022-10-15 14:54:28 -04:00
|
|
|
r(acc, t);
|
2022-10-15 14:44:35 -04:00
|
|
|
}
|
|
|
|
R reduce(C const& container, Reducer reducer) {
|
|
|
|
auto res = R();
|
|
|
|
for (auto& item : container) {
|
|
|
|
reducer(res, item);
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<
|
|
|
|
ValidConstContainer From,
|
|
|
|
ValidContainer Into,
|
|
|
|
ValidIntoConverter<typename From::value_type, typename Into::value_type> Mapper
|
|
|
|
>
|
|
|
|
Into map(From const& from, Mapper mapper) {
|
|
|
|
auto res = Into();
|
|
|
|
std::transform(from.begin(), from.end(), res.end(), mapper);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|