@@ -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") |
@@ -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; | |||
}; | |||
@@ -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()); | |||
} |