nngn
Loading...
Searching...
No Matches
ranges.h
Go to the documentation of this file.
1#ifndef NNGN_UTILS_RANGES_H
2#define NNGN_UTILS_RANGES_H
3
4#include <algorithm>
5#include <cstring>
6#include <iterator>
7#include <numeric>
8#include <ranges>
9#include <span>
10#include <utility>
11
12#include "utils.h"
13
14namespace nngn {
15
16template<typename T>
17using const_iterator = decltype(std::ranges::cbegin(std::declval<T&>()));
18
19template<typename T>
21public:
22 constexpr owning_view(const T&) = delete;
23 constexpr explicit owning_view(T &r);
24 constexpr explicit owning_view(T &&r) : owning_view{r} {}
25 constexpr auto begin(void) const { return this->b; }
26 constexpr auto begin(void) { return this->b; }
27 constexpr auto end(void) const { return this->e; }
28 constexpr auto end(void) { return this->e; }
29private:
30 std::ranges::iterator_t<T> b, e;
31};
32
33template<typename T>
34inline constexpr owning_view<T>::owning_view(T &r) :
35 b{std::move(std::ranges::begin(r))},
36 e{std::move(std::ranges::end(r))}
37{}
38
39template<typename T>
40struct range_to {
41 template<std::ranges::range R>
42 friend auto operator|(R &&r, range_to) {
43 T ret = {};
44 if constexpr(std::ranges::sized_range<R>)
45 ret.reserve(std::ranges::size(FWD(r)));
46 for(auto &&x : FWD(r))
47 ret.push_back(x);
48 return ret;
49 }
50};
51
52/* TODO libc++
53constexpr auto enumerate(std::ranges::range auto &&r, auto i = std::size_t{}) {
54 return std::views::transform(
55 FWD(r), [i](auto &&x) mutable { return std::pair{i++, FWD(x)}; });
56} */
57
58template<typename V>
59void set_capacity(V *v, size_t n) {
60 if(n < v->capacity())
61 V{}.swap(*v);
62 return v->reserve(n);
63}
64
65template<std::size_t N>
66consteval auto to_array(const char *s) {
67 return [&s]<auto ...I>(std::index_sequence<I...>) {
68 return std::array{s[I]...};
69 }(std::make_index_sequence<N>{});
70}
71
72template<std::size_t N>
73consteval auto to_array(const char (&s)[N]) {
74 return to_array<N - 1>(static_cast<const char*>(s));
75}
76
77template<std::size_t N>
78consteval auto to_array(const std::ranges::contiguous_range auto &r) {
79 return to_array<N>(std::data(r));
80}
81
82template<std::size_t N, std::ranges::view V>
83consteval auto to_array(V &&v) {
84 using T = std::ranges::range_value_t<V>;
85 std::array<T, N> ret = {};
86 std::copy_n(std::ranges::begin(v), N, begin(ret));
87 return ret;
88}
89
90constexpr bool contains(
91 const std::ranges::contiguous_range auto &r, const auto &x)
92{
93 return std::ranges::less_equal{}(&*std::ranges::cbegin(r), &x)
94 && std::ranges::less{}(&x, &*std::ranges::cend(r));
95}
96
97constexpr bool in_range(
98 const std::ranges::contiguous_range auto &r, const auto &x)
99{
100 return std::ranges::less_equal{}(&*std::ranges::cbegin(r), &x)
101 && std::ranges::less_equal{}(&x, &*std::ranges::cend(r));
102}
103
104template<std::ranges::forward_range R, typename Proj = std::identity>
105constexpr bool is_sequence(R &&r, Proj proj = {}) {
106 return std::adjacent_find(
107 std::ranges::begin(FWD(r)), std::ranges::end(FWD(r)),
108 [proj]<typename T>(const T &lhs, const T &rhs) {
109 return proj(lhs) + proj(T{1}) != proj(rhs);
110 }
111 ) == end(FWD(r));
112}
113
114template<std::ranges::range R>
115constexpr void iota(R &&r, std::ranges::range_value_t<R> &&x = {}) {
116 std::iota(std::ranges::begin(r), std::ranges::end(r), FWD(x));
117}
118
119constexpr auto reduce(std::ranges::range auto &&r) {
120 return std::reduce(std::ranges::begin(r), std::ranges::end(r));
121}
122
123constexpr auto reduce(
124 std::ranges::range auto &&r, auto &&init = {}, auto &&op = std::plus<>{})
125{
126 return std::reduce(
127 std::ranges::begin(r), std::ranges::end(r),
128 FWD(init), FWD(op));
129}
130
131void const_time_erase(auto *v, auto *p) {
132 assert(contains(*v, *p));
133 auto last = v->end() - 1;
134 *p = std::move(*last);
135 v->erase(last);
136}
137
138template<
139 std::input_iterator I,
140 std::output_iterator<std::iter_value_t<I>> O>
141constexpr void fill_with_pattern(I f, I l, O df, O dl) {
142 std::generate(df, dl, [i = f, f, l](void) mutable {
143 if(i == l)
144 i = f;
145 return *i++;
146 });
147}
148
149template<typename T>
150constexpr T *memcpy(T *dst, std::ranges::contiguous_range auto &&r) {
151 const auto n = std::span{r}.size_bytes();
152 std::memcpy(dst, std::data(FWD(r)), n);
153 return cast<char*>(dst) + n;
154}
155
156template<typename T>
157constexpr T *memmove(T *dst, std::ranges::contiguous_range auto &&r) {
158 const auto n = std::span{r}.size_bytes();
159 std::memmove(dst, std::data(FWD(r)), n);
160 return cast<char*>(dst) + n;
161}
162
163}
164
165namespace std::ranges {
166
167#ifdef DOXYGEN
168template<typename T> inline constexpr bool enable_view;
169template<typename T> inline constexpr bool enable_borrowed_range;
170#endif
171
173template<typename T>
174inline constexpr bool enable_view<nngn::owning_view<T>> = true;
175
177template<typename T>
178inline constexpr bool enable_borrowed_range<nngn::owning_view<T>> = true;
179
180}
181
182#endif
Definition: ranges.h:20
constexpr auto end(void) const
Definition: ranges.h:27
constexpr auto begin(void)
Definition: ranges.h:26
constexpr auto end(void)
Definition: ranges.h:28
constexpr auto begin(void) const
Definition: ranges.h:25
constexpr owning_view(const T &)=delete
constexpr owning_view(T &&r)
Definition: ranges.h:24
std::ranges::iterator_t< T > b
Definition: ranges.h:30
std::ranges::iterator_t< T > e
Definition: ranges.h:30
assert
Definition: debug.lua:3
end
Definition: entities.lua:9
function g l
Definition: plot.lua:8
Definition: debug.h:45
void const_time_erase(auto *v, auto *p)
Definition: ranges.h:131
constexpr const R * begin(const T< R > &v)
Definition: vec.h:207
constexpr auto reduce(std::ranges::range auto &&r)
Definition: ranges.h:119
consteval auto to_array(const char *s)
Definition: ranges.h:66
constexpr void fill_with_pattern(I f, I l, O df, O dl)
Definition: ranges.h:141
void set_capacity(V *v, size_t n)
Definition: ranges.h:59
constexpr bool in_range(const std::ranges::contiguous_range auto &r, const auto &x)
Definition: ranges.h:97
constexpr bool is_sequence(R &&r, Proj proj={})
Definition: ranges.h:105
constexpr void iota(R &&r, std::ranges::range_value_t< R > &&x={})
Definition: ranges.h:115
constexpr T * memcpy(T *dst, std::ranges::contiguous_range auto &&r)
Definition: ranges.h:150
constexpr bool contains(const std::ranges::contiguous_range auto &r, const auto &x)
Definition: ranges.h:90
typedef const_iterator
Definition: ranges.h:17
constexpr T * memmove(T *dst, std::ranges::contiguous_range auto &&r)
Definition: ranges.h:157
Definition: ranges.h:165
Definition: debug.h:13
move
Definition: camera.lua:43
function f()) end
v[1]
Definition: math.lua:19
Definition: ranges.h:40
friend auto operator|(R &&r, range_to)
Definition: ranges.h:42
e
Definition: math.lua:4
std::chrono::seconds s
Definition: timing.cpp:6
function init(ps, k, open_f, init_f)
#define FWD(...)
Definition: utils.h:18