mirror of
https://github.com/mpusz/mp-units.git
synced 2025-08-03 12:24:26 +02:00
refactor: first_factor_maybe()
replaced with get_first_of()
This commit is contained in:
@@ -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))
|
||||
{
|
@@ -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>
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user