Browse Source

nicer syntax for range-y stuff

opengl-renderer-broken
Martin Dørum 4 years ago
parent
commit
91d7ef454c
2 changed files with 30 additions and 3 deletions
  1. 27
    0
      libswan/include/swan/util.h
  2. 3
    3
      libswan/test/util.t.cc

+ 27
- 0
libswan/include/swan/util.h View File

@@ -50,6 +50,18 @@ Deferred<Func> makeDeferred(Func func) {
return Deferred(func);
}

// Calling begin/end is stupid...
template<typename T>
auto callBegin(T &v) {
using namespace std;
return begin(v);
}
template<typename T>
auto callEnd(T &v) {
using namespace std;
return end(v);
}

// Ret can't be a reference, because C++ doesn't support optional<T&>.
template<typename Ret, typename Func = std::function<std::optional<Ret>()>>
class Iter {
@@ -113,6 +125,11 @@ auto map(InputIterator first, InputIterator last, Func func) {
return Iter<RetT, decltype(l)>(l);
}

template<typename Range, typename Func>
auto map(Range &rng, Func func) {
return map(callBegin(rng), callEnd(rng), func);
}

template<typename InputIterator, typename Func>
auto filter(InputIterator first, InputIterator last, Func pred) {
using RetT = std::remove_reference_t<decltype(*first)>;
@@ -135,6 +152,11 @@ auto filter(InputIterator first, InputIterator last, Func pred) {
return Iter<RetT, decltype(l)>(l);
}

template<typename Range, typename Func>
auto filter(Range &rng, Func func) {
return filter(callBegin(rng), callEnd(rng), func);
}

template<typename InputIterator, typename Func>
auto mapFilter(InputIterator first, InputIterator last, Func func) {
using RetT = std::remove_reference_t<decltype(*func(*first))>;
@@ -157,4 +179,9 @@ auto mapFilter(InputIterator first, InputIterator last, Func func) {
return Iter<RetT, decltype(l)>(l);
}

template<typename Range, typename Func>
auto mapFilter(Range &rng, Func func) {
return mapFilter(callBegin(rng), callEnd(rng), func);
}

}

+ 3
- 3
libswan/test/util.t.cc View File

@@ -4,7 +4,7 @@

test("map") {
int ints[] = { 100, 200, 300, 400 };
auto mapping = Swan::map(std::begin(ints), std::end(ints), [](int i) { return i / 10; });
auto mapping = Swan::map(ints, [](int i) { return i / 10; });
auto iter = mapping.begin();

expecteq(*iter, 10); ++iter;
@@ -16,7 +16,7 @@ test("map") {

test("filter") {
int ints[] = { 100, 200, 300, 400 };
auto filter = Swan::filter(std::begin(ints), std::end(ints), [](int i) { return i == 200 || i == 400; });
auto filter = Swan::filter(ints, [](int i) { return i == 200 || i == 400; });
auto iter = filter.begin();

expecteq(*iter, 200); ++iter;
@@ -26,7 +26,7 @@ test("filter") {

test("mapFilter") {
float floats[] = { 10.1, 20.2, 30.3 };
auto mapfilt = Swan::mapFilter(std::begin(floats), std::end(floats), [](float f) -> std::optional<int> {
auto mapfilt = Swan::mapFilter(floats, [](float f) -> std::optional<int> {
if ((int)f == 20)
return std::nullopt;
return (int)f;

Loading…
Cancel
Save