Browse Source

Iter stuff

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

+ 2
- 1
libswan/CMakeLists.txt View File

@@ -22,7 +22,8 @@ target_link_libraries(libswan ${libraries})
install(TARGETS libswan DESTINATION swan/libswan)

add_executable(test_libswan EXCLUDE_FROM_ALL
test/lib/test.cc)
test/lib/test.cc
test/util.t.cc)
target_link_libraries(test_libswan libswan)
target_include_directories(test_libswan
PRIVATE "include/swan")

+ 48
- 3
libswan/include/swan/util.h View File

@@ -4,6 +4,7 @@
#include <functional>
#include <memory>
#include <chrono>
#include <type_traits>

namespace Swan {

@@ -56,11 +57,11 @@ public:
public:
It(std::optional<Ret> next, Func &func): next_(std::move(next)), func_(func) {}

bool operator==(It &other) {
bool operator==(const It &other) {
return next_ == std::nullopt && other.next_ == std::nullopt;
}

bool operator!=(It &other) {
bool operator!=(const It &other) {
return !(*this == other);
}

@@ -104,7 +105,51 @@ auto map(InputIterator first, InputIterator last, Func func) {
return std::nullopt;

RetT r = func(*first);
first++;
++first;
return r;
};

return Iter<RetT, decltype(l)>(l);
}

template<typename InputIterator, typename Func>
auto filter(InputIterator first, InputIterator last, Func pred) {
using RetT = std::remove_reference_t<decltype(*first)>;

auto l = [=]() mutable -> std::optional<RetT> {
if (first == last)
return std::nullopt;

while (!pred(*first)) {
++first;
if (first == last)
return std::nullopt;
}

RetT r = *first;
++first;
return r;
};

return Iter<RetT, decltype(l)>(l);
}

template<typename InputIterator, typename Func>
auto mapFilter(InputIterator first, InputIterator last, Func func) {
using RetT = std::remove_reference_t<decltype(*func(*first))>;

auto l = [=]() mutable -> std::optional<RetT> {
if (first == last)
return std::nullopt;

std::optional<RetT> r;
while ((r = func(*first)) == std::nullopt) {
++first;
if (first == last)
return std::nullopt;
}

++first;
return r;
};


+ 41
- 0
libswan/test/util.t.cc View File

@@ -0,0 +1,41 @@
#include "util.h"

#include <iostream>

#include "lib/test.h"

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

expecteq(*iter, 10); ++iter;
expecteq(*iter, 20); ++iter;
expecteq(*iter, 30); ++iter;
expecteq(*iter, 40); ++iter;
expecteq(iter, mapping.end());
}

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 iter = filter.begin();

expecteq(*iter, 200); ++iter;
expecteq(*iter, 400); ++iter;
expecteq(iter, filter.end());
}

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> {
if ((int)f == 20)
return std::nullopt;
return (int)f;
});
auto iter = mapfilt.begin();

expecteq(*iter, 10); ++iter;
expecteq(*iter, 30); ++iter;
expecteq(iter, mapfilt.end());
}

Loading…
Cancel
Save