8namespace CppClingo::Util {
14template <
class Rng>
auto copy_n(Rng
const &rng,
size_t n) -> std::vector<typename Rng::value_type> {
15 std::vector<std::remove_const_t<typename Rng::value_type>> ret;
16 ret.reserve(rng.size());
17 for (
auto it = rng.begin(), ie = it + n; it != ie; ++it) {
18 ret.emplace_back(*it);
24template <
class T,
class... Ts>
auto make_vec(Ts &&...args) -> std::vector<T> {
26 res.reserve(
sizeof...(Ts));
27 (res.emplace_back(std::forward<Ts>(args)), ...);
32template <
class Container, std::input_iterator It, std::sentinel_for<It> Sent,
typename Pred>
33void into_vec(Container &vec, It first, Sent last, Pred &&pred) {
35 if constexpr (
requires { vec.reserve(std::distance(first, last)); }) {
36 vec.reserve(std::distance(first, last));
38 std::ranges::transform(first, last, std::back_inserter(vec), std::forward<Pred>(pred));
42template <
class Container,
class Rng,
class Pred>
void into_vec(Container &vec, Rng &&rng, Pred &&pred) {
43 into_vec(vec, std::ranges::begin(rng), std::ranges::end(rng), std::forward<Pred>(pred));
47template <
class Container, std::input_iterator It, std::sentinel_for<It> Sent,
typename Pred,
typename... Args>
48auto to_vec(It begin, Sent end, Pred &&pred, Args &&...args) {
49 Container p(std::forward<Args>(args)...);
50 if constexpr (
requires { p.reserve(std::distance(begin, end)); }) {
51 p.reserve(std::distance(begin, end));
53 std::transform(begin, end, std::back_inserter(p), std::forward<Pred>(pred));
58template <
template <
class,
class...>
class Container = std::vector, std::input_iterator It, std::sentinel_for<It> Sent,
59 typename Pred,
typename... Args>
60auto to_vec(It begin, Sent end, Pred &&pred, Args &&...args) {
61 using InputType = std::iter_value_t<It>;
62 using OutputType = std::invoke_result_t<Pred, InputType>;
63 return to_vec<Container<OutputType, Args...>>(begin, end, std::forward<Pred>(pred), std::forward<Args>(args)...);
67template <
template <
class,
class...>
class Container = std::vector, std::ranges::input_range Rng,
typename Pred,
69auto to_vec(Rng &&rng, Pred pred, Args &&...args) {
70 return to_vec<Container>(std::ranges::begin(rng), std::ranges::end(rng), pred, std::forward<Args>(args)...);
74template <
class Container, std::ranges::input_range Rng,
typename Pred,
typename... Args>
75auto to_vec(Rng &&rng, Pred pred, Args &&...args) {
76 return to_vec<Container>(std::ranges::begin(rng), std::ranges::end(rng), pred, std::forward<Args>(args)...);
80template <
class It,
class Pred>
auto transform_n(It begin,
size_t n, Pred pred) {
81 return to_vec(begin, begin + n, pred);
85template <
class Vec,
class Pred>
auto erase_if(Vec &vec, Pred pred) ->
size_t {
86 auto it = std::ranges::remove_if(vec, std::move(pred));
87 auto n = vec.end() - it;
88 vec.erase(it, vec.end());
92#if __cpp_lib_unreachable
93using std::unreachable;
97#if defined(_MSC_VER) && !defined(__clang__)
100 __builtin_unreachable();
auto copy_n(Rng const &rng, size_t n) -> std::vector< typename Rng::value_type >
Return a vector with the first n elements from the given one.
Definition algorithm.hh:14
auto make_vec(Ts &&...args) -> std::vector< T >
Avoids copies of initializer_lists.
Definition algorithm.hh:24
void into_vec(Container &vec, It first, Sent last, Pred &&pred)
Map a range into a vector using a transformation function.
Definition algorithm.hh:33
void unreachable()
C++23's std::unreachable.
Definition algorithm.hh:96
auto erase_if(Vec &vec, Pred pred) -> size_t
Remove all elements from the vector matching the given predicate.
Definition algorithm.hh:85
auto transform_n(It begin, size_t n, Pred pred)
Use std::transform to build a vector.
Definition algorithm.hh:80
auto to_vec(It begin, Sent end, Pred &&pred, Args &&...args)
Use a transformation function to build a vector from a range.
Definition algorithm.hh:48