summaryrefslogtreecommitdiff
path: root/lib/collections.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/collections.h')
-rw-r--r--lib/collections.h73
1 files changed, 70 insertions, 3 deletions
diff --git a/lib/collections.h b/lib/collections.h
index 943b986..dd603be 100644
--- a/lib/collections.h
+++ b/lib/collections.h
@@ -2,6 +2,7 @@
#include <algorithm>
#include <array>
+#include <cstdint>
#include <span>
#include <utility>
#include <vector>
@@ -129,18 +130,25 @@ vectorOfN(std::integral auto N, T start = {}, T step = 1)
return v;
}
+template<template<typename...> typename Rtn = std::vector, typename In>
+[[nodiscard]] auto
+materializeRange(const In begin, const In end)
+{
+ return Rtn(begin, end);
+}
+
template<template<typename...> typename Rtn = std::vector, IterableCollection In>
[[nodiscard]] auto
-materializeRange(In && in)
+materializeRange(const In & in)
{
- return Rtn(in.begin(), in.end());
+ return materializeRange<Rtn>(in.begin(), in.end());
}
template<template<typename...> typename Rtn = std::vector, typename In>
[[nodiscard]] auto
materializeRange(const std::pair<In, In> & in)
{
- return Rtn(in.first, in.second);
+ return materializeRange<Rtn>(in.first, in.second);
}
template<typename T> struct pair_range {
@@ -160,3 +168,62 @@ template<typename T> struct pair_range {
};
template<typename T> pair_range(std::pair<T, T>) -> pair_range<T>;
+
+template<typename iter> struct stripiter {
+ [[nodiscard]] constexpr bool
+ operator!=(const stripiter & other) const
+ {
+ return current != other.current;
+ }
+
+ [[nodiscard]] constexpr bool
+ operator==(const stripiter & other) const
+ {
+ return current == other.current;
+ }
+
+ constexpr stripiter &
+ operator++()
+ {
+ ++current;
+ off = 1 - off;
+ return *this;
+ }
+
+ constexpr stripiter &
+ operator--()
+ {
+ --current;
+ off = 1 - off;
+ return *this;
+ }
+
+ constexpr auto
+ operator-(const stripiter & other) const
+ {
+ return current - other.current;
+ }
+
+ constexpr auto
+ operator*() const
+ {
+ return std::tie(*(current - (2 - off)), *(current - off - 1), *current);
+ }
+
+ iter current;
+ uint8_t off {};
+};
+
+template<typename T> struct std::iterator_traits<stripiter<T>> : std::iterator_traits<T> { };
+
+constexpr auto
+strip_begin(IterableCollection auto & cont)
+{
+ return stripiter {cont.begin() + 2};
+}
+
+constexpr auto
+strip_end(IterableCollection auto & cont)
+{
+ return stripiter {cont.end()};
+}