Commit 2f3f075e authored by Max Kellermann's avatar Max Kellermann

tag/Mask: wrap in class

parent 17097d96
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "client/Client.hxx" #include "client/Client.hxx"
#include "client/Response.hxx" #include "client/Response.hxx"
#include "tag/ParseName.hxx" #include "tag/ParseName.hxx"
#include "tag/Mask.hxx"
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
#include "util/StringAPI.hxx" #include "util/StringAPI.hxx"
#include "SongFilter.hxx" #include "SongFilter.hxx"
...@@ -191,7 +192,7 @@ handle_list(Client &client, Request args, Response &r) ...@@ -191,7 +192,7 @@ handle_list(Client &client, Request args, Response &r)
} }
std::unique_ptr<SongFilter> filter; std::unique_ptr<SongFilter> filter;
tag_mask_t group_mask = 0; TagMask group_mask = TagMask::None();
if (args.size == 1) { if (args.size == 1) {
/* for compatibility with < 0.12.0 */ /* for compatibility with < 0.12.0 */
...@@ -216,7 +217,7 @@ handle_list(Client &client, Request args, Response &r) ...@@ -216,7 +217,7 @@ handle_list(Client &client, Request args, Response &r)
return CommandResult::ERROR; return CommandResult::ERROR;
} }
group_mask |= tag_mask_t(1) << unsigned(gt); group_mask |= gt;
args.pop_back(); args.pop_back();
args.pop_back(); args.pop_back();
...@@ -231,7 +232,7 @@ handle_list(Client &client, Request args, Response &r) ...@@ -231,7 +232,7 @@ handle_list(Client &client, Request args, Response &r)
} }
if (tagType < TAG_NUM_OF_ITEM_TYPES && if (tagType < TAG_NUM_OF_ITEM_TYPES &&
group_mask & (tag_mask_t(1) << tagType)) { group_mask.Test(TagType(tagType))) {
r.Error(ACK_ERROR_ARG, "Conflicting group"); r.Error(ACK_ERROR_ARG, "Conflicting group");
return CommandResult::ERROR; return CommandResult::ERROR;
} }
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "client/Response.hxx" #include "client/Response.hxx"
#include "Partition.hxx" #include "Partition.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/Mask.hxx"
#include "LightSong.hxx" #include "LightSong.hxx"
#include "LightDirectory.hxx" #include "LightDirectory.hxx"
#include "PlaylistInfo.hxx" #include "PlaylistInfo.hxx"
...@@ -202,7 +203,7 @@ PrintUniqueTag(Response &r, TagType tag_type, ...@@ -202,7 +203,7 @@ PrintUniqueTag(Response &r, TagType tag_type,
void void
PrintUniqueTags(Response &r, Partition &partition, PrintUniqueTags(Response &r, Partition &partition,
unsigned type, tag_mask_t group_mask, unsigned type, TagMask group_mask,
const SongFilter *filter) const SongFilter *filter)
{ {
const Database &db = partition.GetDatabaseOrThrow(); const Database &db = partition.GetDatabaseOrThrow();
......
...@@ -20,8 +20,7 @@ ...@@ -20,8 +20,7 @@
#ifndef MPD_DB_PRINT_H #ifndef MPD_DB_PRINT_H
#define MPD_DB_PRINT_H #define MPD_DB_PRINT_H
#include "tag/Mask.hxx" class TagMask;
class SongFilter; class SongFilter;
struct DatabaseSelection; struct DatabaseSelection;
struct Partition; struct Partition;
...@@ -44,7 +43,7 @@ db_selection_print(Response &r, Partition &partition, ...@@ -44,7 +43,7 @@ db_selection_print(Response &r, Partition &partition,
void void
PrintUniqueTags(Response &r, Partition &partition, PrintUniqueTags(Response &r, Partition &partition,
unsigned type, tag_mask_t group_mask, unsigned type, TagMask group_mask,
const SongFilter *filter); const SongFilter *filter);
#endif #endif
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
#include "Visitor.hxx" #include "Visitor.hxx"
#include "tag/Type.h" #include "tag/Type.h"
#include "tag/Mask.hxx"
#include "Compiler.h" #include "Compiler.h"
#include <time.h> #include <time.h>
...@@ -31,6 +30,7 @@ struct DatabasePlugin; ...@@ -31,6 +30,7 @@ struct DatabasePlugin;
struct DatabaseStats; struct DatabaseStats;
struct DatabaseSelection; struct DatabaseSelection;
struct LightSong; struct LightSong;
class TagMask;
class Database { class Database {
const DatabasePlugin &plugin; const DatabasePlugin &plugin;
...@@ -103,7 +103,7 @@ public: ...@@ -103,7 +103,7 @@ public:
* Visit all unique tag values. * Visit all unique tag values.
*/ */
virtual void VisitUniqueTags(const DatabaseSelection &selection, virtual void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag) const = 0; VisitTag visit_tag) const = 0;
gcc_pure gcc_pure
......
...@@ -21,13 +21,14 @@ ...@@ -21,13 +21,14 @@
#include "Interface.hxx" #include "Interface.hxx"
#include "LightSong.hxx" #include "LightSong.hxx"
#include "tag/Set.hxx" #include "tag/Set.hxx"
#include "tag/Mask.hxx"
#include <functional> #include <functional>
#include <assert.h> #include <assert.h>
static void static void
CollectTags(TagSet &set, TagType tag_type, tag_mask_t group_mask, CollectTags(TagSet &set, TagType tag_type, TagMask group_mask,
const LightSong &song) const LightSong &song)
{ {
assert(song.tag != nullptr); assert(song.tag != nullptr);
...@@ -38,7 +39,7 @@ CollectTags(TagSet &set, TagType tag_type, tag_mask_t group_mask, ...@@ -38,7 +39,7 @@ CollectTags(TagSet &set, TagType tag_type, tag_mask_t group_mask,
void void
VisitUniqueTags(const Database &db, const DatabaseSelection &selection, VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag) VisitTag visit_tag)
{ {
TagSet set; TagSet set;
......
...@@ -22,14 +22,14 @@ ...@@ -22,14 +22,14 @@
#include "Visitor.hxx" #include "Visitor.hxx"
#include "tag/Type.h" #include "tag/Type.h"
#include "tag/Mask.hxx"
class TagMask;
class Database; class Database;
struct DatabaseSelection; struct DatabaseSelection;
void void
VisitUniqueTags(const Database &db, const DatabaseSelection &selection, VisitUniqueTags(const Database &db, const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag); VisitTag visit_tag);
#endif #endif
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "config/Block.hxx" #include "config/Block.hxx"
#include "tag/Builder.hxx" #include "tag/Builder.hxx"
#include "tag/Tag.hxx" #include "tag/Tag.hxx"
#include "tag/Mask.hxx"
#include "util/ScopeExit.hxx" #include "util/ScopeExit.hxx"
#include "util/RuntimeError.hxx" #include "util/RuntimeError.hxx"
#include "protocol/Ack.hxx" #include "protocol/Ack.hxx"
...@@ -120,7 +121,7 @@ public: ...@@ -120,7 +121,7 @@ public:
VisitPlaylist visit_playlist) const override; VisitPlaylist visit_playlist) const override;
void VisitUniqueTags(const DatabaseSelection &selection, void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag) const override; VisitTag visit_tag) const override;
DatabaseStats GetStats(const DatabaseSelection &selection) const override; DatabaseStats GetStats(const DatabaseSelection &selection) const override;
...@@ -756,7 +757,7 @@ ProxyDatabase::Visit(const DatabaseSelection &selection, ...@@ -756,7 +757,7 @@ ProxyDatabase::Visit(const DatabaseSelection &selection,
void void
ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection, ProxyDatabase::VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, TagType tag_type,
gcc_unused tag_mask_t group_mask, gcc_unused TagMask group_mask,
VisitTag visit_tag) const VisitTag visit_tag) const
{ {
// TODO: eliminate the const_cast // TODO: eliminate the const_cast
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
#include "DatabaseSave.hxx" #include "DatabaseSave.hxx"
#include "db/DatabaseLock.hxx" #include "db/DatabaseLock.hxx"
#include "db/DatabaseError.hxx" #include "db/DatabaseError.hxx"
#include "tag/Mask.hxx"
#include "fs/io/TextFile.hxx" #include "fs/io/TextFile.hxx"
#include "fs/io/BufferedOutputStream.hxx" #include "fs/io/BufferedOutputStream.hxx"
#include "fs/io/FileOutputStream.hxx" #include "fs/io/FileOutputStream.hxx"
...@@ -301,7 +302,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection, ...@@ -301,7 +302,7 @@ SimpleDatabase::Visit(const DatabaseSelection &selection,
void void
SimpleDatabase::VisitUniqueTags(const DatabaseSelection &selection, SimpleDatabase::VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag) const VisitTag visit_tag) const
{ {
::VisitUniqueTags(*this, selection, tag_type, group_mask, visit_tag); ::VisitUniqueTags(*this, selection, tag_type, group_mask, visit_tag);
......
...@@ -120,7 +120,7 @@ public: ...@@ -120,7 +120,7 @@ public:
VisitPlaylist visit_playlist) const override; VisitPlaylist visit_playlist) const override;
void VisitUniqueTags(const DatabaseSelection &selection, void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag) const override; VisitTag visit_tag) const override;
DatabaseStats GetStats(const DatabaseSelection &selection) const override; DatabaseStats GetStats(const DatabaseSelection &selection) const override;
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "config/Block.hxx" #include "config/Block.hxx"
#include "tag/Builder.hxx" #include "tag/Builder.hxx"
#include "tag/Table.hxx" #include "tag/Table.hxx"
#include "tag/Mask.hxx"
#include "fs/Traits.hxx" #include "fs/Traits.hxx"
#include "Log.hxx" #include "Log.hxx"
#include "SongFilter.hxx" #include "SongFilter.hxx"
...@@ -88,7 +89,7 @@ public: ...@@ -88,7 +89,7 @@ public:
VisitPlaylist visit_playlist) const override; VisitPlaylist visit_playlist) const override;
void VisitUniqueTags(const DatabaseSelection &selection, void VisitUniqueTags(const DatabaseSelection &selection,
TagType tag_type, tag_mask_t group_mask, TagType tag_type, TagMask group_mask,
VisitTag visit_tag) const override; VisitTag visit_tag) const override;
DatabaseStats GetStats(const DatabaseSelection &selection) const override; DatabaseStats GetStats(const DatabaseSelection &selection) const override;
...@@ -605,7 +606,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection, ...@@ -605,7 +606,7 @@ UpnpDatabase::Visit(const DatabaseSelection &selection,
void void
UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection, UpnpDatabase::VisitUniqueTags(const DatabaseSelection &selection,
TagType tag, gcc_unused tag_mask_t group_mask, TagType tag, gcc_unused TagMask group_mask,
VisitTag visit_tag) const VisitTag visit_tag) const
{ {
// TODO: use group_mask // TODO: use group_mask
......
...@@ -37,7 +37,7 @@ TagLoadConfig() ...@@ -37,7 +37,7 @@ TagLoadConfig()
if (value == nullptr) if (value == nullptr)
return; return;
global_tag_mask = 0; global_tag_mask = TagMask::None();
if (StringEqualsCaseASCII(value, "none")) if (StringEqualsCaseASCII(value, "none"))
return; return;
...@@ -60,7 +60,7 @@ TagLoadConfig() ...@@ -60,7 +60,7 @@ TagLoadConfig()
FormatFatalError("error parsing metadata item \"%s\"", FormatFatalError("error parsing metadata item \"%s\"",
c); c);
global_tag_mask |= tag_mask_t(1) << unsigned(type); global_tag_mask |= type;
s++; s++;
c = s; c = s;
......
...@@ -20,8 +20,73 @@ ...@@ -20,8 +20,73 @@
#ifndef MPD_TAG_MASK_HXX #ifndef MPD_TAG_MASK_HXX
#define MPD_TAG_MASK_HXX #define MPD_TAG_MASK_HXX
#include "Type.h"
#include <stdint.h> #include <stdint.h>
typedef uint_least32_t tag_mask_t; class TagMask {
typedef uint_least32_t mask_t;
mask_t value;
explicit constexpr TagMask(uint_least32_t _value)
:value(_value) {}
public:
TagMask() = default;
constexpr TagMask(TagType tag)
:value(mask_t(1) << mask_t(tag)) {}
static constexpr TagMask None() {
return TagMask(mask_t(0));
}
static constexpr TagMask All() {
return ~None();
}
constexpr TagMask operator~() const {
return TagMask(~value);
}
constexpr TagMask operator&(TagMask other) const {
return TagMask(value & other.value);
}
constexpr TagMask operator|(TagMask other) const {
return TagMask(value | other.value);
}
constexpr TagMask operator^(TagMask other) const {
return TagMask(value ^ other.value);
}
TagMask &operator&=(TagMask other) {
value |= other.value;
return *this;
}
TagMask &operator|=(TagMask other) {
value |= other.value;
return *this;
}
TagMask &operator^=(TagMask other) {
value |= other.value;
return *this;
}
constexpr bool TestAny() const {
return value != 0;
}
constexpr bool Test(TagType tag) const {
return (*this & tag).TestAny();
}
void Set(TagType tag) {
*this |= tag;
}
};
#endif #endif
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "Set.hxx" #include "Set.hxx"
#include "Builder.hxx" #include "Builder.hxx"
#include "Mask.hxx"
#include "Settings.hxx" #include "Settings.hxx"
#include <assert.h> #include <assert.h>
...@@ -58,16 +59,16 @@ CopyTagItem(TagBuilder &dest, const Tag &src, TagType type) ...@@ -58,16 +59,16 @@ CopyTagItem(TagBuilder &dest, const Tag &src, TagType type)
* Copy all tag items of the types in the mask. * Copy all tag items of the types in the mask.
*/ */
static void static void
CopyTagMask(TagBuilder &dest, const Tag &src, tag_mask_t mask) CopyTagMask(TagBuilder &dest, const Tag &src, TagMask mask)
{ {
for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i) for (unsigned i = 0; i < TAG_NUM_OF_ITEM_TYPES; ++i)
if ((mask & (tag_mask_t(1) << i)) != 0) if (mask.Test(TagType(i)))
CopyTagItem(dest, src, TagType(i)); CopyTagItem(dest, src, TagType(i));
} }
void void
TagSet::InsertUnique(const Tag &src, TagType type, const char *value, TagSet::InsertUnique(const Tag &src, TagType type, const char *value,
tag_mask_t group_mask) TagMask group_mask)
{ {
TagBuilder builder; TagBuilder builder;
if (value == nullptr) if (value == nullptr)
...@@ -85,7 +86,7 @@ TagSet::InsertUnique(const Tag &src, TagType type, const char *value, ...@@ -85,7 +86,7 @@ TagSet::InsertUnique(const Tag &src, TagType type, const char *value,
bool bool
TagSet::CheckUnique(TagType dest_type, TagSet::CheckUnique(TagType dest_type,
const Tag &tag, TagType src_type, const Tag &tag, TagType src_type,
tag_mask_t group_mask) TagMask group_mask)
{ {
bool found = false; bool found = false;
...@@ -101,12 +102,12 @@ TagSet::CheckUnique(TagType dest_type, ...@@ -101,12 +102,12 @@ TagSet::CheckUnique(TagType dest_type,
void void
TagSet::InsertUnique(const Tag &tag, TagSet::InsertUnique(const Tag &tag,
TagType type, tag_mask_t group_mask) TagType type, TagMask group_mask)
{ {
static_assert(sizeof(group_mask) * 8 >= TAG_NUM_OF_ITEM_TYPES, static_assert(sizeof(group_mask) * 8 >= TAG_NUM_OF_ITEM_TYPES,
"Mask is too small"); "Mask is too small");
assert((group_mask & (tag_mask_t(1) << unsigned(type))) == 0); assert(!group_mask.Test(type));
if (!CheckUnique(type, tag, type, group_mask) && if (!CheckUnique(type, tag, type, group_mask) &&
(type != TAG_ALBUM_ARTIST || (type != TAG_ALBUM_ARTIST ||
......
...@@ -22,12 +22,13 @@ ...@@ -22,12 +22,13 @@
#include "Compiler.h" #include "Compiler.h"
#include "Tag.hxx" #include "Tag.hxx"
#include "Mask.hxx"
#include <set> #include <set>
#include <string.h> #include <string.h>
class TagMask;
/** /**
* Helper class for #TagSet which compares two #Tag objects. * Helper class for #TagSet which compares two #Tag objects.
*/ */
...@@ -59,15 +60,15 @@ struct TagLess { ...@@ -59,15 +60,15 @@ struct TagLess {
class TagSet : public std::set<Tag, TagLess> { class TagSet : public std::set<Tag, TagLess> {
public: public:
void InsertUnique(const Tag &tag, void InsertUnique(const Tag &tag,
TagType type, tag_mask_t group_mask); TagType type, TagMask group_mask);
private: private:
void InsertUnique(const Tag &src, TagType type, const char *value, void InsertUnique(const Tag &src, TagType type, const char *value,
tag_mask_t group_mask); TagMask group_mask);
bool CheckUnique(TagType dest_type, bool CheckUnique(TagType dest_type,
const Tag &tag, TagType src_type, const Tag &tag, TagType src_type,
tag_mask_t group_mask); TagMask group_mask);
}; };
#endif #endif
...@@ -19,4 +19,4 @@ ...@@ -19,4 +19,4 @@
#include "Settings.hxx" #include "Settings.hxx"
tag_mask_t global_tag_mask = (tag_mask_t)-1 & ~(1 << TAG_COMMENT); TagMask global_tag_mask = TagMask::All() & ~TagMask(TAG_COMMENT);
...@@ -24,20 +24,20 @@ ...@@ -24,20 +24,20 @@
#include "Type.h" #include "Type.h"
#include "Compiler.h" #include "Compiler.h"
extern tag_mask_t global_tag_mask; extern TagMask global_tag_mask;
gcc_const gcc_const
static inline bool static inline bool
IsTagEnabled(unsigned tag) IsTagEnabled(TagType tag)
{ {
return global_tag_mask & (1u << tag); return global_tag_mask.Test(tag);
} }
gcc_const gcc_const
static inline bool static inline bool
IsTagEnabled(TagType tag) IsTagEnabled(unsigned tag)
{ {
return IsTagEnabled(unsigned(tag)); return IsTagEnabled(TagType(tag));
} }
#endif #endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment