refactor: first_factor_maybe() replaced with get_first_of()

This commit is contained in:
Mateusz Pusz
2022-03-21 18:13:47 +01:00
parent b822a149b9
commit 6218a709ae
3 changed files with 42 additions and 32 deletions

View File

@@ -24,9 +24,41 @@
#include <units/bits/external/hacks.h> // IWYU pragma: keep
#include <compare>
#include <iterator>
namespace units::detail {
// TODO refactor two below functions with std::ranges when moved to modules
/**
* @brief Returns the first successful value obtained from applying the function object to the elements of a given
* range, if any.
*
* @tparam InputIt must meet the requirements of LegacyInputIterator
* @tparam UnaryFunction must meet the requirements of MoveConstructible
* @param first the beginning of the range of elements to examine
* @param last the end of the range of elements to examine
* @param f function object, to be applied to the result of dereferencing every iterator in the range
* @return std::invoke_result_t<UnaryPredicate, std::iter_value_t<InputIt>>
*/
template<class InputIt, class UnaryFunction>
constexpr std::invoke_result_t<UnaryFunction, std::iter_value_t<InputIt>> get_first_of(InputIt first, InputIt last,
UnaryFunction f)
{
for (; first != last; ++first)
if (auto opt = f(*first)) return *opt;
return {};
}
template<class Rng, class UnaryFunction>
constexpr auto get_first_of(const Rng& rng, UnaryFunction f)
{
using std::begin, std::end;
return get_first_of(begin(rng), end(rng), f);
}
// TODO remove all the below and use std when moved to modules
template<class InputIt1, class InputIt2>
constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
{
@@ -38,17 +70,6 @@ constexpr bool equal(InputIt1 first1, InputIt1 last1, InputIt2 first2)
return true;
}
template<class InputIt, class UnaryPredicate>
constexpr InputIt find_if(InputIt first, InputIt last, UnaryPredicate p)
{
for (; first != last; ++first) {
if (p(*first)) {
return first;
}
}
return last;
}
template<class I1, class I2, class Cmp>
constexpr auto lexicographical_compare_three_way(I1 f1, I1 l1, I2 f2, I2 l2, Cmp comp) -> decltype(comp(*f1, *f2))
{

View File

@@ -24,7 +24,7 @@
#include <units/bits/external/hacks.h> // IWYU pragma: keep
// TODO use <algorithm> when moved to C++20 modules (parsing takes too long for each translation unit)
#include <units/bits/external/algorithm.h>
#include <units/bits/algorithm.h>
// IWYU pragma: begin_exports
#include <compare>

View File

@@ -22,6 +22,7 @@
#pragma once
#include <units/bits/algorithm.h>
#include <array>
#include <cassert>
#include <cstddef>
@@ -55,23 +56,6 @@ constexpr std::optional<std::size_t> first_factor_maybe(std::size_t n, std::size
return std::nullopt;
}
// TODO refactor two below functions with std::ranges when moved to modules
template<class InputIt>
constexpr std::optional<std::size_t> first_factor_maybe(InputIt first, InputIt last, std::size_t n,
std::size_t offset = 0)
{
for (; first != last; ++first)
if (const auto k = first_factor_maybe(n, *first + offset)) return *k;
return {};
}
template<class Rng>
constexpr std::optional<std::size_t> first_factor_maybe(const Rng& rng, std::size_t n, std::size_t offset = 0)
{
using std::begin, std::end;
return first_factor_maybe(begin(rng), end(rng), n, offset);
}
template<std::size_t N>
constexpr std::array<std::size_t, N> first_n_primes()
{
@@ -153,11 +137,16 @@ struct wheel_factorizer {
static constexpr std::size_t find_first_factor(std::size_t n)
{
if (const auto k = first_factor_maybe(basis, n)) return *k;
if (const auto k = first_factor_maybe(std::next(begin(coprimes_in_first_wheel)), end(coprimes_in_first_wheel), n))
if (const auto k = detail::get_first_of(basis, [&](auto p) { return first_factor_maybe(n, p); })) return *k;
if (const auto k = detail::get_first_of(std::next(begin(coprimes_in_first_wheel)), end(coprimes_in_first_wheel),
[&](auto p) { return first_factor_maybe(n, p); }))
return *k;
for (std::size_t wheel = wheel_size; wheel < n; wheel += wheel_size)
if (const auto k = first_factor_maybe(coprimes_in_first_wheel, n, wheel)) return *k;
if (const auto k =
detail::get_first_of(coprimes_in_first_wheel, [&](auto p) { return first_factor_maybe(n, wheel + p); }))
return *k;
return n;
}