Clingo
Loading...
Searching...
No Matches
algorithm.hh
1#pragma once
2
3#include <algorithm>
4#include <iterator>
5#include <type_traits>
6#include <vector>
7
8namespace CppClingo::Util {
9
12
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);
19 }
20 return ret;
21}
22
24template <class T, class... Ts> auto make_vec(Ts &&...args) -> std::vector<T> {
25 std::vector<T> res;
26 res.reserve(sizeof...(Ts));
27 (res.emplace_back(std::forward<Ts>(args)), ...);
28 return res;
29}
30
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) {
34 vec.clear();
35 if constexpr (requires { vec.reserve(std::distance(first, last)); }) {
36 vec.reserve(std::distance(first, last));
37 }
38 std::ranges::transform(first, last, std::back_inserter(vec), std::forward<Pred>(pred));
39}
40
42template <class Container, class Rng, class Pred> void into_vec(Container &vec, Rng &&rng, Pred &&pred) { // NOLINT
43 into_vec(vec, std::ranges::begin(rng), std::ranges::end(rng), std::forward<Pred>(pred));
44}
45
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));
52 }
53 std::transform(begin, end, std::back_inserter(p), std::forward<Pred>(pred));
54 return p;
55}
56
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)...);
64}
65
67template <template <class, class...> class Container = std::vector, std::ranges::input_range Rng, typename Pred,
68 typename... Args>
69auto to_vec(Rng &&rng, Pred pred, Args &&...args) { // NOLINT
70 return to_vec<Container>(std::ranges::begin(rng), std::ranges::end(rng), pred, std::forward<Args>(args)...);
71}
72
74template <class Container, std::ranges::input_range Rng, typename Pred, typename... Args>
75auto to_vec(Rng &&rng, Pred pred, Args &&...args) { // NOLINT
76 return to_vec<Container>(std::ranges::begin(rng), std::ranges::end(rng), pred, std::forward<Args>(args)...);
77}
78
80template <class It, class Pred> auto transform_n(It begin, size_t n, Pred pred) {
81 return to_vec(begin, begin + n, pred);
82}
83
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());
89 return n;
90}
91
92#if __cpp_lib_unreachable
93using std::unreachable;
94#else
96[[noreturn]] inline void unreachable() {
97#if defined(_MSC_VER) && !defined(__clang__) // MSVC
98 __assume(false);
99#else // GCC, Clang
100 __builtin_unreachable();
101#endif
102}
103#endif
104
106
107} // namespace CppClingo::Util
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