basedOpinionated utility library |
git clone git://git.dimitrijedobrota.com/based.git |
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING |
commit | 0bc4b5da4aea6b51681aeaea21ddffcfe87b9510 |
parent | d1259323ef4d4cf80573dc14c76064af133a49bd |
author | Dimitrije Dobrota <mail@dimitrijedobrota.com> |
date | Sat, 5 Apr 2025 18:04:10 +0200 |
Test new algorithms and fix some issues
Diffstat:M | include/based/algorithm.hpp | | | +++++++++++++++++++++++++++---------------------------- |
M | include/based/type_traits.hpp | | | ++++++++++++-- |
M | test/CMakeLists.txt | | | +++++ |
A | test/source/count_if_test.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test/source/count_test.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test/source/find_if_test.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test/source/find_test.cpp | | | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
A | test/source/for_each_test.cpp | | | ++++++++++++++++++++++++++++++++++++++++++++ |
8 files changed, 721 insertions(+), 30 deletions(-)
diff --git a/include/based/algorithm.hpp b/include/based/algorithm.hpp
@@ -168,7 +168,7 @@ I find(I f, I d, const iter_value_t<I>& x)
{
// Precondition: readable_bounded_range(f, d);
while (f != d && *f != x) {
f == next(f);
f = next(f);
}
return f;
}
@@ -178,7 +178,7 @@ I find_not(I f, I d, const iter_value_t<I>& x)
{
// Precondition: readable_bounded_range(f, d);
while (f != d && *f == x) {
f == next(f);
f = next(f);
}
return f;
}
@@ -189,7 +189,7 @@ I find_if(I f, I d, P p)
{
// Precondition: readable_bounded_range(f, d);
while (f != d && !p(*f)) {
f == next(f);
f = next(f);
}
return f;
}
@@ -200,7 +200,7 @@ I find_if_not(I f, I d, P p)
{
// Precondition: readable_bounded_range(f, d);
while (f != d && p(*f)) {
f == next(f);
f = next(f);
}
return f;
}
@@ -226,7 +226,7 @@ template<ReadableIterator I, UnaryPredicate P>
bool not_all(I f, I d, P p)
{
// Precondition: readable_bounded_range(f, d);
return find_if_not(f, d, p) != d;
return f == d || find_if_not(f, d, p) != d;
}
template<ReadableIterator I, UnaryPredicate P>
@@ -237,13 +237,12 @@ bool some(I f, I d, P p)
return find_if(f, d, p) != d;
}
template<ReadableIterator I, UnaryPredicate P, Iterator J>
requires SameAs<iter_value_t<I>, domain_t<P>>
J count_if(I f, I d, P p, J j)
template<ReadableIterator I, Iterator J>
J count(I f, I d, const iter_value_t<I>& x, J j)
{
// Precondition: readable_bounded_range(f, d);
while (f != d) {
if (p(*f)) {
if (*f == x) {
j = next(j);
}
f = next(f);
@@ -251,20 +250,18 @@ J count_if(I f, I d, P p, J j)
return j;
}
template<ReadableIterator I, UnaryPredicate P>
requires SameAs<iter_value_t<I>, domain_t<P>>
iter_dist_t<I> count_if(I f, I d, P p)
template<ReadableIterator I>
iter_dist_t<I> count(I f, I d, const iter_value_t<I>& x)
{
// Precondition: readable_bounded_range(f, d);
return count_if(f, d, p, iter_dist_t<I> {0});
return count(f, d, x, iter_dist_t<I> {0});
}
template<ReadableIterator I, Iterator J>
J count(I f, I d, const iter_value_t<I>& x, J j)
J count_not(I f, I d, const iter_value_t<I>& x, J j)
{
// Precondition: readable_bounded_range(f, d);
while (f != d) {
if (*f == x) {
if (*f != x) {
j = next(j);
}
f = next(f);
@@ -273,19 +270,19 @@ J count(I f, I d, const iter_value_t<I>& x, J j)
}
template<ReadableIterator I>
iter_dist_t<I> count(I f, I d, const iter_value_t<I>& x)
iter_dist_t<I> count_not(I f, I d, const iter_value_t<I>& x)
{
// Precondition: readable_bounded_range(f, d);
return count(f, d, x, iter_dist_t<I> {0});
return count_not(f, d, x, iter_dist_t<I> {0});
}
template<ReadableIterator I, UnaryPredicate P, Iterator J>
requires SameAs<iter_value_t<I>, domain_t<P>>
J count_if_not(I f, I d, P p, J j)
J count_if(I f, I d, P p, J j)
{
// Precondition: readable_bounded_range(f, d);
while (f != d) {
if (!p(*f)) {
if (p(*f)) {
j = next(j);
}
f = next(f);
@@ -295,18 +292,19 @@ J count_if_not(I f, I d, P p, J j)
template<ReadableIterator I, UnaryPredicate P>
requires SameAs<iter_value_t<I>, domain_t<P>>
iter_dist_t<I> count_if_not(I f, I d, P p)
iter_dist_t<I> count_if(I f, I d, P p)
{
// Precondition: readable_bounded_range(f, d);
return count_if_not(f, d, p, iter_dist_t<I> {0});
return count_if(f, d, p, iter_dist_t<I> {0});
}
template<ReadableIterator I, Iterator J>
J count_not(I f, I d, const iter_value_t<I>& x, J j)
template<ReadableIterator I, UnaryPredicate P, Iterator J>
requires SameAs<iter_value_t<I>, domain_t<P>>
J count_if_not(I f, I d, P p, J j)
{
// Precondition: readable_bounded_range(f, d);
while (f != d) {
if (*f != x) {
if (!p(*f)) {
j = next(j);
}
f = next(f);
@@ -314,11 +312,12 @@ J count_not(I f, I d, const iter_value_t<I>& x, J j)
return j;
}
template<ReadableIterator I>
iter_dist_t<I> count_not(I f, I d, const iter_value_t<I>& x)
template<ReadableIterator I, UnaryPredicate P>
requires SameAs<iter_value_t<I>, domain_t<P>>
iter_dist_t<I> count_if_not(I f, I d, P p)
{
// Precondition: readable_bounded_range(f, d);
return count_not(f, d, x, iter_dist_t<I> {0});
return count_if_not(f, d, p, iter_dist_t<I> {0});
}
} // namespace based
diff --git a/include/based/type_traits.hpp b/include/based/type_traits.hpp
@@ -50,12 +50,22 @@ concept BareSameAs = SameAs<bare_t<T>, bare_t<U>>;
namespace detail {
template<typename I>
struct iterator_traits {
using value_type = I;
using distance_type = std::uint64_t;
using pointer_type = I&;
using reference_type = I*;
};
template<typename I>
requires std::input_or_output_iterator<I>
struct iterator_traits<I> {
using value_type = std::iterator_traits<I>::value_type;
using distance_type = std::iterator_traits<I>::difference_type;
using pointer_type = std::iterator_traits<I>::pointer;
using reference_type = std::iterator_traits<I>::reference;
};
} // namespace detail
@@ -74,8 +84,8 @@ using iter_ref_t = detail::iterator_traits<T>::reference;
template<typename T>
concept Readable = requires(T t) {
requires(Regular<T>);
typename T::value_type;
{ *t } -> std::same_as<typename T::value_type>;
typename iter_value_t<T>;
{ *t } -> BareSameAs<iter_value_t<T>>;
};
template<typename T>
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
@@ -27,6 +27,11 @@ add_test(min_element_test)
add_test(max_test)
add_test(max_element_test)
add_test(minmax_element_test)
add_test(for_each_test)
add_test(find_test)
add_test(find_if_test)
add_test(count_test)
add_test(count_if_test)
# ---- List ----
add_test(list_test)
diff --git a/test/source/count_if_test.cpp b/test/source/count_if_test.cpp
@@ -0,0 +1,126 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "based/algorithm.hpp"
#include "based/type_traits.hpp"
struct predicate
{
int goal;
explicit predicate(int init)
: goal(init)
{
}
auto operator()(int n) const { return n == goal; }
};
TEST_CASE("count_if return type", "[algorithm/count_if]")
{
std::array<int, 0> arr = {};
REQUIRE(based::SameAs<based::iter_dist_t<decltype(arr)::iterator>,
decltype(based::count_if(
std::begin(arr), std::end(arr), predicate {0}))>);
REQUIRE(based::SameAs<std::uint8_t,
decltype(based::count_if(std::begin(arr),
std::end(arr),
predicate {0},
std::uint8_t {0}))>);
}
TEST_CASE("count_if(empty)", "[algorithm/count_if]")
{
std::array<int, 0> arr = {};
const auto count =
based::count_if(std::begin(arr), std::end(arr), predicate {0});
REQUIRE(count == 0);
}
TEST_CASE("count_if(homogeneous)", "[algorithm/count_if]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
const auto count0 =
based::count_if(std::begin(arr), std::end(arr), predicate {0});
const auto count1 =
based::count_if(std::begin(arr), std::end(arr), predicate {1});
REQUIRE(count0 == 0);
REQUIRE(count1 == 6);
}
TEST_CASE("count_if(non homogeneous)", "[algorithm/count_if]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
const auto count0 =
based::count_if(std::begin(arr), std::end(arr), predicate {0});
const auto count1 =
based::count_if(std::begin(arr), std::end(arr), predicate {1});
const auto count2 =
based::count_if(std::begin(arr), std::end(arr), predicate {2});
REQUIRE(count0 == 0);
REQUIRE(count1 == 4);
REQUIRE(count2 == 2);
}
TEST_CASE("count_if_not return type", "[algorithm/count_if_not]")
{
std::array<int, 0> arr = {};
REQUIRE(based::SameAs<based::iter_dist_t<decltype(arr)::iterator>,
decltype(based::count_if_not(
std::begin(arr), std::end(arr), predicate {0}))>);
REQUIRE(based::SameAs<std::uint8_t,
decltype(based::count_if_not(std::begin(arr),
std::end(arr),
predicate {0},
std::uint8_t {0}))>);
}
TEST_CASE("count_if_not(empty)", "[algorithm/count_if_not]")
{
std::array<int, 0> arr = {};
const auto count =
based::count_if_not(std::begin(arr), std::end(arr), predicate {0});
REQUIRE(count == 0);
}
TEST_CASE("count_if_not(homogeneous)", "[algorithm/count_if_not]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
const auto count0 =
based::count_if_not(std::begin(arr), std::end(arr), predicate {0});
const auto count1 =
based::count_if_not(std::begin(arr), std::end(arr), predicate {1});
REQUIRE(count0 == 6);
REQUIRE(count1 == 0);
}
TEST_CASE("count_if_not(non homogeneous)", "[algorithm/count_if_not]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
const auto count0 =
based::count_if_not(std::begin(arr), std::end(arr), predicate {0});
const auto count1 =
based::count_if_not(std::begin(arr), std::end(arr), predicate {1});
const auto count2 =
based::count_if_not(std::begin(arr), std::end(arr), predicate {2});
REQUIRE(count0 == 6);
REQUIRE(count1 == 2);
REQUIRE(count2 == 4);
}
diff --git a/test/source/count_test.cpp b/test/source/count_test.cpp
@@ -0,0 +1,100 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "based/algorithm.hpp"
#include "based/type_traits.hpp"
TEST_CASE("count return type", "[algorithm/count]")
{
std::array<int, 0> arr = {};
REQUIRE(
based::SameAs<based::iter_dist_t<decltype(arr)::iterator>,
decltype(based::count(std::begin(arr), std::end(arr), 0))>);
REQUIRE(
based::SameAs<std::uint8_t,
decltype(based::count(
std::begin(arr), std::end(arr), 0, std::uint8_t {0}))>);
}
TEST_CASE("count(empty)", "[algorithm/count]")
{
std::array<int, 0> arr = {};
const auto count = based::count(std::begin(arr), std::end(arr), 0);
REQUIRE(count == 0);
}
TEST_CASE("count(homogeneous)", "[algorithm/count]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
const auto count0 = based::count(std::begin(arr), std::end(arr), 0);
const auto count1 = based::count(std::begin(arr), std::end(arr), 1);
REQUIRE(count0 == 0);
REQUIRE(count1 == 6);
}
TEST_CASE("count(non homogeneous)", "[algorithm/count]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
const auto count0 = based::count(std::begin(arr), std::end(arr), 0);
const auto count1 = based::count(std::begin(arr), std::end(arr), 1);
const auto count2 = based::count(std::begin(arr), std::end(arr), 2);
REQUIRE(count0 == 0);
REQUIRE(count1 == 4);
REQUIRE(count2 == 2);
}
TEST_CASE("count_not return type", "[algorithm/count_not]")
{
std::array<int, 0> arr = {};
REQUIRE(based::SameAs<based::iter_dist_t<decltype(arr)::iterator>,
decltype(based::count_not(
std::begin(arr), std::end(arr), 0))>);
REQUIRE(
based::SameAs<std::uint8_t,
decltype(based::count_not(
std::begin(arr), std::end(arr), 0, std::uint8_t {0}))>);
}
TEST_CASE("count_not(empty)", "[algorithm/count_not]")
{
std::array<int, 0> arr = {};
const auto count_not = based::count_not(std::begin(arr), std::end(arr), 0);
REQUIRE(count_not == 0);
}
TEST_CASE("count_not(homogeneous)", "[algorithm/count_not]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
const auto count0 = based::count_not(std::begin(arr), std::end(arr), 0);
const auto count1 = based::count_not(std::begin(arr), std::end(arr), 1);
REQUIRE(count0 == 6);
REQUIRE(count1 == 0);
}
TEST_CASE("count_not(non homogeneous)", "[algorithm/count_not]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
const auto count0 = based::count_not(std::begin(arr), std::end(arr), 0);
const auto count1 = based::count_not(std::begin(arr), std::end(arr), 1);
const auto count2 = based::count_not(std::begin(arr), std::end(arr), 2);
REQUIRE(count0 == 6);
REQUIRE(count1 == 2);
REQUIRE(count2 == 4);
}
diff --git a/test/source/find_if_test.cpp b/test/source/find_if_test.cpp
@@ -0,0 +1,265 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "based/algorithm.hpp"
struct predicate
{
int goal;
explicit predicate(int init)
: goal(init)
{
}
auto operator()(int n) const { return n == goal; }
};
TEST_CASE("find_if(empty)", "[algorithm/find_if]")
{
std::array<int, 0> arr = {};
const auto* it =
based::find_if(std::begin(arr), std::end(arr), predicate {0});
REQUIRE(it == std::end(arr));
}
TEST_CASE("find_if(one) = found", "[algorithm/find_if]")
{
std::array arr = {0};
SECTION("found")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
}
TEST_CASE("find_if(two) = found", "[algorithm/find_if]")
{
std::array arr = {0, 1};
SECTION("found 1")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("found 2")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
SECTION("not found")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {2});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 2);
}
}
TEST_CASE("find_if(multiple) = found", "[algorithm/find_if]")
{
std::array arr = {0, 0, 0, 0};
SECTION("found")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr =
based::find_if(std::begin(arr), std::end(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 4);
}
}
TEST_CASE("find_if_not(empty)", "[algorithm/find_if_not]")
{
std::array<int, 0> arr = {};
const auto* it =
based::find_if_not(std::begin(arr), std::end(arr), predicate {0});
REQUIRE(it == std::end(arr));
}
TEST_CASE("find_if_not(one) = found", "[algorithm/find_if_not]")
{
std::array arr = {0};
SECTION("found")
{
const auto* itr =
based::find_if_not(std::begin(arr), std::end(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr =
based::find_if_not(std::begin(arr), std::end(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
}
TEST_CASE("find_if_not(two) = found", "[algorithm/find_if_not]")
{
std::array arr = {0, 1};
SECTION("found 1")
{
const auto* itr =
based::find_if_not(std::begin(arr), std::end(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("found 2")
{
const auto* itr =
based::find_if_not(std::begin(arr), std::end(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
}
TEST_CASE("find_if_not(multiple) = found", "[algorithm/find_if_not]")
{
std::array arr = {0, 0, 0, 0};
SECTION("found")
{
const auto* itr =
based::find_if_not(std::begin(arr), std::end(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr =
based::find_if_not(std::begin(arr), std::end(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 4);
}
}
TEST_CASE("all(empty)", "[algorithm/all]")
{
std::array<int, 0> arr = {};
REQUIRE(based::all(std::begin(arr), std::end(arr), predicate {0}));
}
TEST_CASE("all(homogeneous)", "[algorithm/all]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
REQUIRE(based::all(std::begin(arr), std::end(arr), predicate {1}));
REQUIRE(!based::all(std::begin(arr), std::end(arr), predicate {2}));
}
TEST_CASE("all(non homogenous)", "[algorithm/all]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
REQUIRE(!based::all(std::begin(arr), std::end(arr), predicate {1}));
REQUIRE(!based::all(std::begin(arr), std::end(arr), predicate {2}));
}
TEST_CASE("none(empty)", "[algorithm/none]")
{
std::array<int, 0> arr = {};
REQUIRE(based::none(std::begin(arr), std::end(arr), predicate {0}));
}
TEST_CASE("none(homogeneous)", "[algorithm/none]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
REQUIRE(based::none(std::begin(arr), std::end(arr), predicate {2}));
REQUIRE(!based::none(std::begin(arr), std::end(arr), predicate {1}));
}
TEST_CASE("none(non homogeneous)", "[algorithm/none]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
REQUIRE(based::none(std::begin(arr), std::end(arr), predicate {0}));
REQUIRE(!based::none(std::begin(arr), std::end(arr), predicate {2}));
REQUIRE(!based::none(std::begin(arr), std::end(arr), predicate {1}));
}
TEST_CASE("not_all(empty)", "[algorithm/not_all]")
{
std::array<int, 0> arr = {};
REQUIRE(based::not_all(std::begin(arr), std::end(arr), predicate {0}));
}
TEST_CASE("not_all(homogeneous)", "[algorithm/not_all]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
REQUIRE(based::not_all(std::begin(arr), std::end(arr), predicate {2}));
REQUIRE(!based::not_all(std::begin(arr), std::end(arr), predicate {1}));
}
TEST_CASE("not_all(non homogeneous)", "[algorithm/not_all]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
REQUIRE(based::not_all(std::begin(arr), std::end(arr), predicate {0}));
REQUIRE(based::not_all(std::begin(arr), std::end(arr), predicate {1}));
REQUIRE(based::not_all(std::begin(arr), std::end(arr), predicate {2}));
}
TEST_CASE("some(empty)", "[algorithm/some]")
{
std::array<int, 0> arr = {};
REQUIRE(!based::some(std::begin(arr), std::end(arr), predicate {0}));
}
TEST_CASE("some(homogeneous)", "[algorithm/some]")
{
std::array arr = {1, 1, 1, 1, 1, 1};
REQUIRE(based::some(std::begin(arr), std::end(arr), predicate {1}));
REQUIRE(!based::some(std::begin(arr), std::end(arr), predicate {2}));
}
TEST_CASE("some(non homogeneous)", "[algorithm/some]")
{
std::array arr = {1, 2, 1, 1, 1, 2};
REQUIRE(based::some(std::begin(arr), std::end(arr), predicate {1}));
REQUIRE(based::some(std::begin(arr), std::end(arr), predicate {2}));
REQUIRE(!based::some(std::begin(arr), std::end(arr), predicate {0}));
}
diff --git a/test/source/find_test.cpp b/test/source/find_test.cpp
@@ -0,0 +1,142 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "based/algorithm.hpp"
TEST_CASE("find(empty)", "[algorithm/find]")
{
std::array<int, 0> arr = {};
const auto* it = based::find(std::begin(arr), std::end(arr), 0);
REQUIRE(it == std::end(arr));
}
TEST_CASE("find(one) = found", "[algorithm/find]")
{
std::array arr = {0};
SECTION("found")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 0);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 1);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
}
TEST_CASE("find(two) = found", "[algorithm/find]")
{
std::array arr = {0, 1};
SECTION("found 1")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 0);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("found 2")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 1);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
SECTION("not found")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 2);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 2);
}
}
TEST_CASE("find(multiple) = found", "[algorithm/find]")
{
std::array arr = {0, 0, 0, 0};
SECTION("found")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 0);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr = based::find(std::begin(arr), std::end(arr), 1);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 4);
}
}
TEST_CASE("find_not(empty)", "[algorithm/find_not]")
{
std::array<int, 0> arr = {};
const auto* it = based::find_not(std::begin(arr), std::end(arr), 0);
REQUIRE(it == std::end(arr));
}
TEST_CASE("find_not(one) = found", "[algorithm/find_not]")
{
std::array arr = {0};
SECTION("found")
{
const auto* itr = based::find_not(std::begin(arr), std::end(arr), 1);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr = based::find_not(std::begin(arr), std::end(arr), 0);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
}
TEST_CASE("find_not(two) = found", "[algorithm/find_not]")
{
std::array arr = {0, 1};
SECTION("found 1")
{
const auto* itr = based::find_not(std::begin(arr), std::end(arr), 1);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("found 2")
{
const auto* itr = based::find_not(std::begin(arr), std::end(arr), 0);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
}
TEST_CASE("find_not(multiple) = found", "[algorithm/find_not]")
{
std::array arr = {0, 0, 0, 0};
SECTION("found")
{
const auto* itr = based::find_not(std::begin(arr), std::end(arr), 1);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
SECTION("not found")
{
const auto* itr = based::find_not(std::begin(arr), std::end(arr), 0);
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 4);
}
}
diff --git a/test/source/for_each_test.cpp b/test/source/for_each_test.cpp
@@ -0,0 +1,44 @@
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "based/algorithm.hpp"
struct functor
{
int operator()(int n) { return sum += n; }
int sum = 0;
};
TEST_CASE("for_each(empty)", "[algorithm/for_each]")
{
std::array<int, 0> arr = {};
const auto f = based::for_each(std::begin(arr), std::end(arr), functor {});
REQUIRE(f.sum == 0);
}
TEST_CASE("for_each(one)", "[algorithm/for_each]")
{
std::array arr = {1};
const auto f = based::for_each(std::begin(arr), std::end(arr), functor {});
REQUIRE(f.sum == 1);
}
TEST_CASE("for_each(two)", "[algorithm/for_each]")
{
std::array arr = {1, 2};
const auto f = based::for_each(std::begin(arr), std::end(arr), functor {});
REQUIRE(f.sum == 3);
}
TEST_CASE("for_each(three)", "[algorithm/for_each]")
{
std::array arr = {1, 2, 3};
const auto f = based::for_each(std::begin(arr), std::end(arr), functor {});
REQUIRE(f.sum == 6);
}