song/StringFilter: move `negated` flag from containing class

This commit is contained in:
Max Kellermann 2018-11-07 23:47:31 +01:00
parent db51cc4e02
commit 73b22d82aa
7 changed files with 53 additions and 26 deletions

View File

@ -58,11 +58,11 @@ OptimizeSongFilter(ISongFilterPtr f) noexcept
/* #TagSongFilter has its own "negated" flag, /* #TagSongFilter has its own "negated" flag,
so we can drop the #NotSongFilter so we can drop the #NotSongFilter
container */ container */
tf->negated = !tf->negated; tf->ToggleNegated();
return child; return child;
} else if (auto *uf = dynamic_cast<UriSongFilter *>(child.get())) { } else if (auto *uf = dynamic_cast<UriSongFilter *>(child.get())) {
/* same for #UriSongFilter */ /* same for #UriSongFilter */
uf->negated = !uf->negated; uf->ToggleNegated();
return child; return child;
} }

View File

@ -23,8 +23,8 @@
#include <assert.h> #include <assert.h>
bool inline bool
StringFilter::Match(const char *s) const noexcept StringFilter::MatchWithoutNegation(const char *s) const noexcept
{ {
#if !CLANG_CHECK_VERSION(3,6) #if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */ /* disabled on clang due to -Wtautological-pointer-compare */
@ -41,3 +41,9 @@ StringFilter::Match(const char *s) const noexcept
: value == s; : value == s;
} }
} }
bool
StringFilter::Match(const char *s) const noexcept
{
return MatchWithoutNegation(s) != negated;
}

View File

@ -38,14 +38,16 @@ class StringFilter {
*/ */
bool substring; bool substring;
bool negated;
public: public:
template<typename V> template<typename V>
StringFilter(V &&_value, bool _fold_case, bool _substring) StringFilter(V &&_value, bool _fold_case, bool _substring, bool _negated)
:value(std::forward<V>(_value)), :value(std::forward<V>(_value)),
fold_case(_fold_case fold_case(_fold_case
? IcuCompare(value.c_str()) ? IcuCompare(value.c_str())
: IcuCompare()), : IcuCompare()),
substring(_substring) {} substring(_substring), negated(_negated) {}
bool empty() const noexcept { bool empty() const noexcept {
return value.empty(); return value.empty();
@ -59,8 +61,24 @@ public:
return fold_case; return fold_case;
} }
bool IsNegated() const noexcept {
return negated;
}
void ToggleNegated() noexcept {
negated = !negated;
}
const char *GetOperator() const noexcept {
return negated ? "!=" : "==";
}
gcc_pure gcc_pure
bool Match(const char *s) const noexcept; bool Match(const char *s) const noexcept;
private:
gcc_pure
bool MatchWithoutNegation(const char *s) const noexcept;
}; };
#endif #endif

View File

@ -31,7 +31,8 @@ TagSongFilter::ToExpression() const noexcept
? "any" ? "any"
: tag_item_names[type]; : tag_item_names[type];
return std::string("(") + name + " " + (negated ? "!=" : "==") + " \"" + EscapeFilterString(filter.GetValue()) + "\")"; return std::string("(") + name + " " + filter.GetOperator()
+ " \"" + EscapeFilterString(filter.GetValue()) + "\")";
} }
bool bool
@ -89,5 +90,5 @@ TagSongFilter::MatchNN(const Tag &tag) const noexcept
bool bool
TagSongFilter::Match(const LightSong &song) const noexcept TagSongFilter::Match(const LightSong &song) const noexcept
{ {
return MatchNN(song.tag) != negated; return MatchNN(song.tag);
} }

View File

@ -34,18 +34,15 @@ struct LightSong;
class TagSongFilter final : public ISongFilter { class TagSongFilter final : public ISongFilter {
TagType type; TagType type;
bool negated;
StringFilter filter; StringFilter filter;
friend ISongFilterPtr OptimizeSongFilter(ISongFilterPtr) noexcept;
public: public:
template<typename V> template<typename V>
TagSongFilter(TagType _type, V &&_value, bool fold_case, bool substring, TagSongFilter(TagType _type, V &&_value, bool fold_case, bool substring,
bool _negated) bool negated)
:type(_type), negated(_negated), :type(_type),
filter(std::forward<V>(_value), fold_case, substring) {} filter(std::forward<V>(_value), fold_case, substring,
negated) {}
TagType GetTagType() const { TagType GetTagType() const {
return type; return type;
@ -60,7 +57,11 @@ public:
} }
bool IsNegated() const noexcept { bool IsNegated() const noexcept {
return negated; return filter.IsNegated();
}
void ToggleNegated() noexcept {
filter.ToggleNegated();
} }
ISongFilterPtr Clone() const noexcept override { ISongFilterPtr Clone() const noexcept override {

View File

@ -25,11 +25,12 @@
std::string std::string
UriSongFilter::ToExpression() const noexcept UriSongFilter::ToExpression() const noexcept
{ {
return std::string("(file ") + (negated ? "!=" : "==") + " \"" + EscapeFilterString(filter.GetValue()) + "\")"; return std::string("(file ") + filter.GetOperator()
+ " \"" + EscapeFilterString(filter.GetValue()) + "\")";
} }
bool bool
UriSongFilter::Match(const LightSong &song) const noexcept UriSongFilter::Match(const LightSong &song) const noexcept
{ {
return filter.Match(song.GetURI().c_str()) != negated; return filter.Match(song.GetURI().c_str());
} }

View File

@ -26,16 +26,12 @@
class UriSongFilter final : public ISongFilter { class UriSongFilter final : public ISongFilter {
StringFilter filter; StringFilter filter;
bool negated;
friend ISongFilterPtr OptimizeSongFilter(ISongFilterPtr) noexcept;
public: public:
template<typename V> template<typename V>
UriSongFilter(V &&_value, bool fold_case, bool substring, UriSongFilter(V &&_value, bool fold_case, bool substring,
bool _negated) bool negated)
:filter(std::forward<V>(_value), fold_case, substring), :filter(std::forward<V>(_value), fold_case, substring,
negated(_negated) {} negated) {}
const auto &GetValue() const noexcept { const auto &GetValue() const noexcept {
return filter.GetValue(); return filter.GetValue();
@ -46,7 +42,11 @@ public:
} }
bool IsNegated() const noexcept { bool IsNegated() const noexcept {
return negated; return filter.IsNegated();
}
void ToggleNegated() noexcept {
filter.ToggleNegated();
} }
ISongFilterPtr Clone() const noexcept override { ISongFilterPtr Clone() const noexcept override {