summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <frrrwww@gmail.com>2016-08-29 23:56:22 +0100
committerMaxime Coste <frrrwww@gmail.com>2016-08-29 23:56:22 +0100
commitcbe38b2f962443f5fefcbbb5f7552f50c0e841fc (patch)
tree85a82f0afb84a5cc217bcefd336c5c81989a55ee
parent95c21a4ebd60c8f52f0b6dea2bb82f9ae6b0014d (diff)
Use flags and bit operations instead of bools in RankedMatch
full match is now the most important flag for comparison.
-rw-r--r--src/flags.hh16
-rw-r--r--src/ranked_match.cc35
-rw-r--r--src/ranked_match.hh17
3 files changed, 47 insertions, 21 deletions
diff --git a/src/flags.hh b/src/flags.hh
index 6b72ba05..824d37ca 100644
--- a/src/flags.hh
+++ b/src/flags.hh
@@ -37,6 +37,9 @@ struct TestableFlags
Flags value;
constexpr operator bool() const { return (UnderlyingType<Flags>)value; }
constexpr operator Flags() const { return value; }
+
+ bool operator==(const TestableFlags<Flags>& other) const { return value == other.value; }
+ bool operator!=(const TestableFlags<Flags>& other) const { return value != other.value; }
};
template<typename Flags, typename = EnableIfWithBitOps<Flags>>
@@ -58,6 +61,19 @@ constexpr Flags operator~(Flags lhs)
return (Flags)(~(UnderlyingType<Flags>)lhs);
}
+template<typename Flags, typename = EnableIfWithBitOps<Flags>>
+constexpr Flags operator^(Flags lhs, Flags rhs)
+{
+ return (Flags)((UnderlyingType<Flags>) lhs ^ (UnderlyingType<Flags>) rhs);
+}
+
+template<typename Flags, typename = EnableIfWithBitOps<Flags>>
+Flags& operator^=(Flags& lhs, Flags rhs)
+{
+ (UnderlyingType<Flags>&) lhs ^= (UnderlyingType<Flags>) rhs;
+ return lhs;
+}
+
}
#endif // flags_hh_INCLUDED
diff --git a/src/ranked_match.cc b/src/ranked_match.cc
index 67be7038..d61d95f5 100644
--- a/src/ranked_match.cc
+++ b/src/ranked_match.cc
@@ -70,9 +70,9 @@ static bool smartcase_eq(Codepoint query, Codepoint candidate)
return query == (islower(query) ? to_lower(candidate) : candidate);
}
-static bool subsequence_match_smart_case(StringView str, StringView subseq, int& index_sum)
+static bool subsequence_match_smart_case(StringView str, StringView subseq, int& out_index_sum)
{
- index_sum = 0;
+ int index_sum = 0;
auto it = str.begin();
int index = 0;
for (auto subseq_it = subseq.begin(); subseq_it != subseq.end();)
@@ -88,6 +88,7 @@ static bool subsequence_match_smart_case(StringView str, StringView subseq, int&
}
index_sum += index++;
}
+ out_index_sum = index_sum;
return true;
}
@@ -103,10 +104,17 @@ RankedMatch::RankedMatch(StringView candidate, StringView query, TestFunc func)
{
m_candidate = candidate;
- m_first_char_match = smartcase_eq(query[0], candidate[0]);
+ if (smartcase_eq(query[0], candidate[0]))
+ m_flags |= Flags::FirstCharMatch;
+ if (std::equal(query.begin(), query.end(), candidate.begin()))
+ {
+ m_flags |= Flags::Prefix;
+ if (query.length() == candidate.length())
+ m_flags |= Flags::FullMatch;
+ }
m_word_boundary_match_count = count_word_boundaries_match(candidate, query);
- m_only_word_boundary = m_word_boundary_match_count == query.length();
- m_prefix = std::equal(query.begin(), query.end(), candidate.begin());
+ if (m_word_boundary_match_count == query.length())
+ m_flags |= Flags::OnlyWordBoundary;
}
}
@@ -127,19 +135,10 @@ bool RankedMatch::operator<(const RankedMatch& other) const
{
kak_assert((bool)*this and (bool)other);
- if (m_prefix != other.m_prefix)
- return m_prefix;
-
- if (m_first_char_match != other.m_first_char_match)
- return m_first_char_match;
-
- if (m_only_word_boundary and other.m_only_word_boundary)
- {
- if (m_word_boundary_match_count != other.m_word_boundary_match_count)
- return m_word_boundary_match_count > other.m_word_boundary_match_count;
- }
- else if (m_only_word_boundary or other.m_only_word_boundary)
- return m_only_word_boundary;
+ const auto diff = m_flags ^ other.m_flags;
+ // flags are different, use their ordering to return the first match
+ if (diff != Flags::None)
+ return (int)(m_flags & diff) > (int)(other.m_flags & diff);
if (m_word_boundary_match_count != other.m_word_boundary_match_count)
return m_word_boundary_match_count > other.m_word_boundary_match_count;
diff --git a/src/ranked_match.hh b/src/ranked_match.hh
index 0e0e49c4..35d76e15 100644
--- a/src/ranked_match.hh
+++ b/src/ranked_match.hh
@@ -2,6 +2,7 @@
#define ranked_match_hh_INCLUDED
#include "string.hh"
+#include "flags.hh"
namespace Kakoune
{
@@ -32,14 +33,24 @@ private:
template<typename TestFunc>
RankedMatch(StringView candidate, StringView query, TestFunc test);
+ enum class Flags : int
+ {
+ None = 0,
+ // Order is important, the highest bit has precedence for comparison
+ OnlyWordBoundary = 1 << 0,
+ FirstCharMatch = 1 << 1,
+ Prefix = 1 << 2,
+ FullMatch = 1 << 3,
+ };
+
StringView m_candidate;
- bool m_first_char_match = false;
- bool m_prefix = false;
+ Flags m_flags = Flags::None;
int m_word_boundary_match_count = 0;
int m_match_index_sum = 0;
- bool m_only_word_boundary = false;
};
+template<> struct WithBitOps<RankedMatch::Flags> : std::true_type {};
+
}
#endif // ranked_match_hh_INCLUDED