Skip to content

Commit

Permalink
finish C++14 support
Browse files Browse the repository at this point in the history
  • Loading branch information
maxbachmann committed Dec 25, 2024
1 parent 4e928a1 commit 369e4d1
Show file tree
Hide file tree
Showing 26 changed files with 335 additions and 307 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ add_library(rapidfuzz INTERFACE)
# provide a namespaced alias for clients to 'link' against if RapidFuzz is included as a sub-project
add_library(rapidfuzz::rapidfuzz ALIAS rapidfuzz)

target_compile_features(rapidfuzz INTERFACE cxx_std_11)
target_compile_features(rapidfuzz INTERFACE cxx_std_14)

target_include_directories(rapidfuzz
INTERFACE
Expand Down
192 changes: 103 additions & 89 deletions extras/rapidfuzz_amalgamated.hpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion fuzzing/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function(create_fuzzer fuzzer)
add_executable(fuzz_${fuzzer} fuzz_${fuzzer}.cpp)
target_compile_features(fuzz_${fuzzer} PUBLIC cxx_std_11)
target_compile_features(fuzz_${fuzzer} PUBLIC cxx_std_14)
target_link_libraries(fuzz_${fuzzer} PRIVATE rapidfuzz::rapidfuzz)

target_compile_options(fuzz_${fuzzer} PRIVATE -g -O1 -fsanitize=fuzzer,address -march=native)
Expand Down
4 changes: 2 additions & 2 deletions fuzzing/fuzz_levenshtein_editops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
validate_editops(s1, s2, score, score);

if (s1.size() > 1 && s2.size() > 1) {
auto hpos = rapidfuzz::detail::find_hirschberg_pos(rapidfuzz::detail::Range(s1),
rapidfuzz::detail::Range(s2));
auto hpos = rapidfuzz::detail::find_hirschberg_pos(rapidfuzz::detail::make_range(s1),
rapidfuzz::detail::make_range(s2));
if (hpos.left_score + hpos.right_score != score)
throw std::logic_error("find_hirschberg_pos failed");
}
Expand Down
19 changes: 13 additions & 6 deletions rapidfuzz/details/Range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,8 @@ class Range {
{}

template <typename T>
constexpr Range(T& x) : _first(to_begin(x)), _last(to_end(x))
{
assert(std::distance(_first, _last) >= 0);
_size = static_cast<size_t>(std::distance(_first, _last));
}
constexpr Range(T& x) : Range(to_begin(x), to_end(x))
{}

constexpr iterator begin() const noexcept
{
Expand Down Expand Up @@ -176,8 +173,18 @@ class Range {
}
};

template <typename Iter>
constexpr auto make_range(Iter first, Iter last) -> Range<Iter>
{
return Range<Iter>(first, last);
}

template <typename T>
Range(T& x) -> Range<decltype(to_begin(x))>;
constexpr auto make_range(T& x) -> Range<decltype(to_begin(x))>
{
auto first = to_begin(x);
return Range<decltype(first)>(first, to_end(x));
}

template <typename InputIt1, typename InputIt2>
inline bool operator==(const Range<InputIt1>& a, const Range<InputIt2>& b)
Expand Down
108 changes: 56 additions & 52 deletions rapidfuzz/details/distance.hpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion rapidfuzz/details/type_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct is_explicitly_convertible {
static bool const value = test<From, To>(0);
};

template<bool B, class T = void>
template <bool B, class T = void>
using rf_enable_if_t = typename std::enable_if<B, T>::type;

} // namespace rapidfuzz
4 changes: 2 additions & 2 deletions rapidfuzz/distance/Hamming.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,15 @@ template <typename InputIt1, typename InputIt2>
Editops hamming_editops(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2, bool pad_ = true,
size_t score_hint = std::numeric_limits<size_t>::max())
{
return detail::hamming_editops(detail::Range(first1, last1), detail::Range(first2, last2), pad_,
return detail::hamming_editops(detail::make_range(first1, last1), detail::make_range(first2, last2), pad_,
score_hint);
}

template <typename Sentence1, typename Sentence2>
Editops hamming_editops(const Sentence1& s1, const Sentence2& s2, bool pad_ = true,
size_t score_hint = std::numeric_limits<size_t>::max())
{
return detail::hamming_editops(detail::Range(s1), detail::Range(s2), pad_, score_hint);
return detail::hamming_editops(detail::make_range(s1), detail::make_range(s2), pad_, score_hint);
}

/**
Expand Down
11 changes: 6 additions & 5 deletions rapidfuzz/distance/Jaro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ struct MultiJaro : public detail::MultiSimilarityBase<MultiJaro<MaxLen>, double,
friend detail::MultiSimilarityBase<MultiJaro<MaxLen>, double, 0, 1>;
friend detail::MultiNormalizedMetricBase<MultiJaro<MaxLen>, double>;

static_assert(MaxLen == 8 || MaxLen == 16 || MaxLen == 32 || MaxLen == 64);
static_assert(MaxLen == 8 || MaxLen == 16 || MaxLen == 32 || MaxLen == 64, "incorrect MaxLen used");

using VecType = typename std::conditional<
MaxLen == 8, uint8_t,
typename std::conditional<MaxLen == 16, uint16_t,
typename std::conditional<MaxLen == 32, uint32_t, uint64_t>::type>::type>::type;
typename std::conditional<MaxLen == 32, uint32_t, uint64_t>::type>::type>::
type;

constexpr static size_t get_vec_size()
{
Expand Down Expand Up @@ -166,7 +167,7 @@ struct MultiJaro : public detail::MultiSimilarityBase<MultiJaro<MaxLen>, double,
if (score_count < result_count())
throw std::invalid_argument("scores has to have >= result_count() elements");

detail::Range scores_(scores, scores + score_count);
auto scores_ = detail::make_range(scores, scores + score_count);
detail::jaro_similarity_simd<VecType>(scores_, PM, str_lens, str_lens_size, s2, score_cutoff);
}

Expand Down Expand Up @@ -198,7 +199,7 @@ struct CachedJaro : public detail::CachedSimilarityBase<CachedJaro<CharT1>, doub
{}

template <typename InputIt1>
CachedJaro(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::Range(first1, last1))
CachedJaro(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::make_range(first1, last1))
{}

private:
Expand All @@ -215,7 +216,7 @@ struct CachedJaro : public detail::CachedSimilarityBase<CachedJaro<CharT1>, doub
double _similarity(const detail::Range<InputIt2>& s2, double score_cutoff,
[[maybe_unused]] double score_hint) const
{
return detail::jaro_similarity(PM, detail::Range(s1), s2, score_cutoff);
return detail::jaro_similarity(PM, detail::make_range(s1), s2, score_cutoff);
}

std::vector<CharT1> s1;
Expand Down
4 changes: 2 additions & 2 deletions rapidfuzz/distance/JaroWinkler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ struct CachedJaroWinkler : public detail::CachedSimilarityBase<CachedJaroWinkler

template <typename InputIt1>
CachedJaroWinkler(InputIt1 first1, InputIt1 last1, double _prefix_weight = 0.1)
: prefix_weight(_prefix_weight), s1(first1, last1), PM(detail::Range(first1, last1))
: prefix_weight(_prefix_weight), s1(first1, last1), PM(detail::make_range(first1, last1))
{}

private:
Expand All @@ -191,7 +191,7 @@ struct CachedJaroWinkler : public detail::CachedSimilarityBase<CachedJaroWinkler
double _similarity(const detail::Range<InputIt2>& s2, double score_cutoff,
[[maybe_unused]] double score_hint) const
{
return detail::jaro_winkler_similarity(PM, detail::Range(s1), s2, prefix_weight, score_cutoff);
return detail::jaro_winkler_similarity(PM, detail::make_range(s1), s2, prefix_weight, score_cutoff);
}

double prefix_weight;
Expand Down
12 changes: 6 additions & 6 deletions rapidfuzz/distance/LCSseq.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ double lcs_seq_normalized_similarity(const Sentence1& s1, const Sentence2& s2, d
template <typename InputIt1, typename InputIt2>
Editops lcs_seq_editops(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2)
{
return detail::lcs_seq_editops(detail::Range(first1, last1), detail::Range(first2, last2));
return detail::lcs_seq_editops(detail::make_range(first1, last1), detail::make_range(first2, last2));
}

template <typename Sentence1, typename Sentence2>
Editops lcs_seq_editops(const Sentence1& s1, const Sentence2& s2)
{
return detail::lcs_seq_editops(detail::Range(s1), detail::Range(s2));
return detail::lcs_seq_editops(detail::make_range(s1), detail::make_range(s2));
}

#ifdef RAPIDFUZZ_SIMD
Expand Down Expand Up @@ -99,7 +99,7 @@ struct MultiLCSseq : public detail::MultiSimilarityBase<MultiLCSseq<MaxLen>, siz
else RAPIDFUZZ_IF_CONSTEXPR (MaxLen <= 64)
return native_simd<uint64_t>::size;

static_assert(MaxLen <= 64);
static_assert(MaxLen <= 64, "expected MaxLen <= 64");
}

constexpr static size_t find_block_count(size_t count)
Expand Down Expand Up @@ -164,7 +164,7 @@ struct MultiLCSseq : public detail::MultiSimilarityBase<MultiLCSseq<MaxLen>, siz
if (score_count < result_count())
throw std::invalid_argument("scores has to have >= result_count() elements");

detail::Range scores_(scores, scores + score_count);
auto scores_ = detail::make_range(scores, scores + score_count);
RAPIDFUZZ_IF_CONSTEXPR (MaxLen == 8)
detail::lcs_simd<uint8_t>(scores_, PM, s2, score_cutoff);
else RAPIDFUZZ_IF_CONSTEXPR (MaxLen == 16)
Expand Down Expand Up @@ -202,7 +202,7 @@ struct CachedLCSseq
{}

template <typename InputIt1>
CachedLCSseq(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::Range(first1, last1))
CachedLCSseq(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::make_range(first1, last1))
{}

private:
Expand All @@ -219,7 +219,7 @@ struct CachedLCSseq
size_t _similarity(const detail::Range<InputIt2>& s2, size_t score_cutoff,
[[maybe_unused]] size_t score_hint) const
{
return detail::lcs_seq_similarity(PM, detail::Range(s1), s2, score_cutoff);
return detail::lcs_seq_similarity(PM, detail::make_range(s1), s2, score_cutoff);
}

std::vector<CharT1> s1;
Expand Down
16 changes: 8 additions & 8 deletions rapidfuzz/distance/Levenshtein.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -283,15 +283,15 @@ template <typename InputIt1, typename InputIt2>
Editops levenshtein_editops(InputIt1 first1, InputIt1 last1, InputIt2 first2, InputIt2 last2,
size_t score_hint = std::numeric_limits<size_t>::max())
{
return detail::levenshtein_editops(detail::Range(first1, last1), detail::Range(first2, last2),
return detail::levenshtein_editops(detail::make_range(first1, last1), detail::make_range(first2, last2),
score_hint);
}

template <typename Sentence1, typename Sentence2>
Editops levenshtein_editops(const Sentence1& s1, const Sentence2& s2,
size_t score_hint = std::numeric_limits<size_t>::max())
{
return detail::levenshtein_editops(detail::Range(s1), detail::Range(s2), score_hint);
return detail::levenshtein_editops(detail::make_range(s1), detail::make_range(s2), score_hint);
}

#ifdef RAPIDFUZZ_SIMD
Expand Down Expand Up @@ -320,7 +320,7 @@ struct MultiLevenshtein : public detail::MultiDistanceBase<MultiLevenshtein<MaxL
else RAPIDFUZZ_IF_CONSTEXPR (MaxLen <= 64)
return native_simd<uint64_t>::size;

static_assert(MaxLen <= 64);
static_assert(MaxLen <= 64, "expected MaxLen <= 64");
}

constexpr static size_t find_block_count(size_t count)
Expand Down Expand Up @@ -387,7 +387,7 @@ struct MultiLevenshtein : public detail::MultiDistanceBase<MultiLevenshtein<MaxL
if (score_count < result_count())
throw std::invalid_argument("scores has to have >= result_count() elements");

detail::Range scores_(scores, scores + score_count);
auto scores_ = detail::make_range(scores, scores + score_count);
RAPIDFUZZ_IF_CONSTEXPR (MaxLen == 8)
detail::levenshtein_hyrroe2003_simd<uint8_t>(scores_, PM, str_lens, s2, score_cutoff);
else RAPIDFUZZ_IF_CONSTEXPR (MaxLen == 16)
Expand Down Expand Up @@ -428,7 +428,7 @@ struct CachedLevenshtein : public detail::CachedDistanceBase<CachedLevenshtein<C

template <typename InputIt1>
CachedLevenshtein(InputIt1 first1, InputIt1 last1, LevenshteinWeightTable aWeights = {1, 1, 1})
: s1(first1, last1), PM(detail::Range(first1, last1)), weights(aWeights)
: s1(first1, last1), PM(detail::make_range(first1, last1)), weights(aWeights)
{}

private:
Expand All @@ -454,7 +454,7 @@ struct CachedLevenshtein : public detail::CachedDistanceBase<CachedLevenshtein<C
// max can make use of the common divisor of the three weights
size_t new_score_cutoff = detail::ceil_div(score_cutoff, weights.insert_cost);
size_t new_score_hint = detail::ceil_div(score_hint, weights.insert_cost);
size_t dist = detail::uniform_levenshtein_distance(PM, detail::Range(s1), s2,
size_t dist = detail::uniform_levenshtein_distance(PM, detail::make_range(s1), s2,
new_score_cutoff, new_score_hint);
dist *= weights.insert_cost;

Expand All @@ -467,13 +467,13 @@ struct CachedLevenshtein : public detail::CachedDistanceBase<CachedLevenshtein<C
else if (weights.replace_cost >= weights.insert_cost + weights.delete_cost) {
// max can make use of the common divisor of the three weights
size_t new_max = detail::ceil_div(score_cutoff, weights.insert_cost);
size_t dist = detail::indel_distance(PM, detail::Range(s1), s2, new_max);
size_t dist = detail::indel_distance(PM, detail::make_range(s1), s2, new_max);
dist *= weights.insert_cost;
return (dist <= score_cutoff) ? dist : score_cutoff + 1;
}
}

return detail::generalized_levenshtein_distance(detail::Range(s1), s2, weights, score_cutoff);
return detail::generalized_levenshtein_distance(detail::make_range(s1), s2, weights, score_cutoff);
}

std::vector<CharT1> s1;
Expand Down
10 changes: 5 additions & 5 deletions rapidfuzz/distance/OSA.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ struct MultiOSA
else RAPIDFUZZ_IF_CONSTEXPR (MaxLen <= 64)
return native_simd<uint64_t>::size;

static_assert(MaxLen <= 64);
static_assert(MaxLen <= 64, "expected MaxLen <= 64");
}

constexpr static size_t find_block_count(size_t count)
Expand Down Expand Up @@ -199,7 +199,7 @@ struct MultiOSA
if (score_count < result_count())
throw std::invalid_argument("scores has to have >= result_count() elements");

detail::Range scores_(scores, scores + score_count);
auto scores_ = detail::make_range(scores, scores + score_count);
RAPIDFUZZ_IF_CONSTEXPR (MaxLen == 8)
detail::osa_hyrroe2003_simd<uint8_t>(scores_, PM, str_lens, s2, score_cutoff);
else RAPIDFUZZ_IF_CONSTEXPR (MaxLen == 16)
Expand Down Expand Up @@ -237,7 +237,7 @@ struct CachedOSA
{}

template <typename InputIt1>
CachedOSA(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::Range(first1, last1))
CachedOSA(InputIt1 first1, InputIt1 last1) : s1(first1, last1), PM(detail::make_range(first1, last1))
{}

private:
Expand All @@ -260,9 +260,9 @@ struct CachedOSA
else if (s2.empty())
res = s1.size();
else if (s1.size() < 64)
res = detail::osa_hyrroe2003(PM, detail::Range(s1), s2, score_cutoff);
res = detail::osa_hyrroe2003(PM, detail::make_range(s1), s2, score_cutoff);
else
res = detail::osa_hyrroe2003_block(PM, detail::Range(s1), s2, score_cutoff);
res = detail::osa_hyrroe2003_block(PM, detail::make_range(s1), s2, score_cutoff);

return (res <= score_cutoff) ? res : score_cutoff + 1;
}
Expand Down
6 changes: 3 additions & 3 deletions rapidfuzz/fuzz.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct MultiRatio {
void similarity(double* scores, size_t score_count, InputIt2 first2, InputIt2 last2,
double score_cutoff = 0.0) const
{
similarity(scores, score_count, detail::Range(first2, last2), score_cutoff);
similarity(scores, score_count, detail::make_range(first2, last2), score_cutoff);
}

template <typename Sentence2>
Expand Down Expand Up @@ -746,13 +746,13 @@ struct MultiQRatio {
void similarity(double* scores, size_t score_count, InputIt2 first2, InputIt2 last2,
double score_cutoff = 0.0) const
{
similarity(scores, score_count, detail::Range(first2, last2), score_cutoff);
similarity(scores, score_count, detail::make_range(first2, last2), score_cutoff);
}

template <typename Sentence2>
void similarity(double* scores, size_t score_count, const Sentence2& s2, double score_cutoff = 0) const
{
rapidfuzz::detail::Range s2_(s2);
auto s2_ = detail::make_range(s2);
if (s2_.empty()) {
for (size_t i = 0; i < str_lens.size(); ++i)
scores[i] = 0;
Expand Down
Loading

0 comments on commit 369e4d1

Please sign in to comment.