based

Opinionated utility library
git clone git://git.dimitrijedobrota.com/based.git
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commitb24481d5115e90a161f8e10d9becd165f5aeab25
parent04604e394557ca3e96f6ebc54d254543f694e1e1
authorDimitrije Dobrota <mail@dimitrijedobrota.com>
dateWed, 9 Apr 2025 18:00:26 +0200

Sentinel Ranges with tests

Diffstat:
Minclude/based/algorithm.hpp|++++++++++++++++++++++
Mtest/CMakeLists.txt|++++-
Mtest/source/find_if_n_test.cpp|++++++------
Mtest/source/find_if_test.cpp|++++++------
Atest/source/find_if_unguarded_test.cpp|+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mtest/source/find_n_test.cpp|++++++------

6 files changed, 119 insertions(+), 19 deletions(-)


diff --git a/include/based/algorithm.hpp b/include/based/algorithm.hpp

@@ -546,4 +546,26 @@ auto count_if_not_n(I f, iter_dist_t<I> n, P p)

return count_if_not_n(f, n, p, iter_dist_t<I> {0});
}
/* ----- Sentinel Ranges ----- */
template<ReadableIterator I, IterUnaryPredicate<I> P>
I find_if_unguarded(I f, P p)
{
// Precondition: readable_bounded_range(f, d) && some(f, d, p);
while (!p(*f)) {
f = successor(f);
}
return f;
}
template<ReadableIterator I, IterUnaryPredicate<I> P>
I find_if_not_unguarded(I f, P p)
{
// Precondition: readable_bounded_range(f, d) && not_all(f, d, p);
while (p(*f)) {
f = successor(f);
}
return f;
}
} // namespace based

diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt

@@ -40,7 +40,6 @@ add_test(count_test)

add_test(count_if_test)
add_test(reduce_test)
## ----- Bounden Range -----
add_test(for_each_n_test)

@@ -49,6 +48,10 @@ add_test(find_if_n_test)

add_test(count_n_test)
add_test(count_if_n_test)
## ----- Unguarded Range -----
add_test(find_if_unguarded_test)
# ---- List ----
add_test(list_test)

diff --git a/test/source/find_if_n_test.cpp b/test/source/find_if_n_test.cpp

@@ -25,7 +25,7 @@ TEST_CASE("find_if_n(empty)", "[algorithm/find_if_n]")

REQUIRE(itr == std::end(arr));
}
TEST_CASE("find_if_n(one) = found", "[algorithm/find_if_n]")
TEST_CASE("find_if_n(one)", "[algorithm/find_if_n]")
{
const std::array arr = {0};

@@ -50,7 +50,7 @@ TEST_CASE("find_if_n(one) = found", "[algorithm/find_if_n]")

}
}
TEST_CASE("find_if_n(two) = found", "[algorithm/find_if_n]")
TEST_CASE("find_if_n(two)", "[algorithm/find_if_n]")
{
const std::array arr = {0, 1};

@@ -85,7 +85,7 @@ TEST_CASE("find_if_n(two) = found", "[algorithm/find_if_n]")

}
}
TEST_CASE("find_if_n(multiple) = found", "[algorithm/find_if_n]")
TEST_CASE("find_if_n(multiple)", "[algorithm/find_if_n]")
{
const std::array arr = {0, 0, 0, 0};

@@ -119,7 +119,7 @@ TEST_CASE("find_if_not_n(empty)", "[algorithm/find_if_not_n]")

REQUIRE(itr == std::end(arr));
}
TEST_CASE("find_if_not_n(one) = found", "[algorithm/find_if_not_n]")
TEST_CASE("find_if_not_n(one)", "[algorithm/find_if_not_n]")
{
const std::array arr = {0};

@@ -145,7 +145,7 @@ TEST_CASE("find_if_not_n(one) = found", "[algorithm/find_if_not_n]")

}
}
TEST_CASE("find_if_not_n(two) = found", "[algorithm/find_if_not_n]")
TEST_CASE("find_if_not_n(two)", "[algorithm/find_if_not_n]")
{
const std::array arr = {0, 1};

@@ -169,7 +169,7 @@ TEST_CASE("find_if_not_n(two) = found", "[algorithm/find_if_not_n]")

}
}
TEST_CASE("find_if_not_n(multiple) = found", "[algorithm/find_if_not_n]")
TEST_CASE("find_if_not_n(multiple)", "[algorithm/find_if_not_n]")
{
const std::array arr = {0, 0, 0, 0};

diff --git a/test/source/find_if_test.cpp b/test/source/find_if_test.cpp

@@ -25,7 +25,7 @@ TEST_CASE("find_if(empty)", "[algorithm/find_if]")

REQUIRE(it == std::end(arr));
}
TEST_CASE("find_if(one) = found", "[algorithm/find_if]")
TEST_CASE("find_if(one)", "[algorithm/find_if]")
{
const std::array arr = {0};

@@ -46,7 +46,7 @@ TEST_CASE("find_if(one) = found", "[algorithm/find_if]")

}
}
TEST_CASE("find_if(two) = found", "[algorithm/find_if]")
TEST_CASE("find_if(two)", "[algorithm/find_if]")
{
const std::array arr = {0, 1};

@@ -75,7 +75,7 @@ TEST_CASE("find_if(two) = found", "[algorithm/find_if]")

}
}
TEST_CASE("find_if(multiple) = found", "[algorithm/find_if]")
TEST_CASE("find_if(multiple)", "[algorithm/find_if]")
{
const std::array arr = {0, 0, 0, 0};

@@ -105,7 +105,7 @@ TEST_CASE("find_if_not(empty)", "[algorithm/find_if_not]")

REQUIRE(it == std::end(arr));
}
TEST_CASE("find_if_not(one) = found", "[algorithm/find_if_not]")
TEST_CASE("find_if_not(one)", "[algorithm/find_if_not]")
{
const std::array arr = {0};

@@ -127,7 +127,7 @@ TEST_CASE("find_if_not(one) = found", "[algorithm/find_if_not]")

}
}
TEST_CASE("find_if_not(two) = found", "[algorithm/find_if_not]")
TEST_CASE("find_if_not(two)", "[algorithm/find_if_not]")
{
const std::array arr = {0, 1};

@@ -148,7 +148,7 @@ TEST_CASE("find_if_not(two) = found", "[algorithm/find_if_not]")

}
}
TEST_CASE("find_if_not(multiple) = found", "[algorithm/find_if_not]")
TEST_CASE("find_if_not(multiple)", "[algorithm/find_if_not]")
{
const std::array arr = {0, 0, 0, 0};

diff --git a/test/source/find_if_unguarded_test.cpp b/test/source/find_if_unguarded_test.cpp

@@ -0,0 +1,75 @@

#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_unguarded(one)", "[algorithm/find_if_unguarded]")
{
const std::array arr = {0};
const auto* itr = based::find_if_unguarded(std::begin(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
TEST_CASE("find_if_unguarded(two)", "[algorithm/find_if_unguarded]")
{
const std::array arr = {0, 1};
const auto* itr = based::find_if_unguarded(std::begin(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
TEST_CASE("find_if_unguarded(multiple)", "[algorithm/find_if_unguarded]")
{
const std::array arr = {0, 0, 0, 0};
const auto* itr = based::find_if_unguarded(std::begin(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
TEST_CASE("find_if_not_unguarded(one)", "[algorithm/find_if_not_unguarded]")
{
const std::array arr = {0};
const auto* itr =
based::find_if_not_unguarded(std::begin(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 0);
}
TEST_CASE("find_if_not_unguarded(two)", "[algorithm/find_if_not_unguarded]")
{
const std::array arr = {0, 1};
const auto* itr =
based::find_if_not_unguarded(std::begin(arr), predicate {0});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 1);
}
TEST_CASE("find_if_not_unguarded(multiple)",
"[algorithm/find_if_not_unguarded]")
{
const std::array arr = {1, 1, 0, 1};
const auto* itr =
based::find_if_not_unguarded(std::begin(arr), predicate {1});
const auto idx = std::distance(std::cbegin(arr), itr);
REQUIRE(idx == 2);
}

diff --git a/test/source/find_n_test.cpp b/test/source/find_n_test.cpp

@@ -14,7 +14,7 @@ TEST_CASE("find_n(empty)", "[algorithm/find_n]")

REQUIRE(idx + left == std::size(arr));
}
TEST_CASE("find_n(one) = found", "[algorithm/find_n]")
TEST_CASE("find_n(one)", "[algorithm/find_n]")
{
const std::array arr = {0};

@@ -36,7 +36,7 @@ TEST_CASE("find_n(one) = found", "[algorithm/find_n]")

}
}
TEST_CASE("find_n(two) = found", "[algorithm/find_n]")
TEST_CASE("find_n(two)", "[algorithm/find_n]")
{
const std::array arr = {0, 1};

@@ -68,7 +68,7 @@ TEST_CASE("find_n(two) = found", "[algorithm/find_n]")

}
}
TEST_CASE("find_n(multiple) = found", "[algorithm/find_n]")
TEST_CASE("find_n(multiple)", "[algorithm/find_n]")
{
const std::array arr = {0, 0, 0, 0};

@@ -103,7 +103,7 @@ TEST_CASE("find_not_n(empty)", "[algorithm/find_not_n]")

REQUIRE(idx + left == std::size(arr));
}
TEST_CASE("find_not_n(one) = found", "[algorithm/find_not_n]")
TEST_CASE("find_not_n(one)", "[algorithm/find_not_n]")
{
const std::array arr = {0};

@@ -128,7 +128,7 @@ TEST_CASE("find_not_n(one) = found", "[algorithm/find_not_n]")

}
}
TEST_CASE("find_not_n(two) = found", "[algorithm/find_not_n]")
TEST_CASE("find_not_n(two)", "[algorithm/find_not_n]")
{
const std::array arr = {0, 1};

@@ -153,7 +153,7 @@ TEST_CASE("find_not_n(two) = found", "[algorithm/find_not_n]")

}
}
TEST_CASE("find_not_n(multiple) = found", "[algorithm/find_not_n]")
TEST_CASE("find_not_n(multiple)", "[algorithm/find_not_n]")
{
const std::array arr = {0, 0, 0, 0};