Tag: add class const_iterator and methods begin(), end()
Enables using range-based "for".
This commit is contained in:
parent
543a58bb87
commit
41a7203c28
|
@ -92,10 +92,10 @@ SongFilter::Item::Match(const Tag &_tag) const
|
|||
bool visited_types[TAG_NUM_OF_ITEM_TYPES];
|
||||
std::fill_n(visited_types, size_t(TAG_NUM_OF_ITEM_TYPES), false);
|
||||
|
||||
for (unsigned i = 0; i < _tag.num_items; i++) {
|
||||
visited_types[_tag.items[i]->type] = true;
|
||||
for (const auto &i : _tag) {
|
||||
visited_types[i.type] = true;
|
||||
|
||||
if (Match(*_tag.items[i]))
|
||||
if (Match(i))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -112,12 +112,10 @@ SongFilter::Item::Match(const Tag &_tag) const
|
|||
if (tag == TAG_ALBUM_ARTIST && visited_types[TAG_ARTIST]) {
|
||||
/* if we're looking for "album artist", but
|
||||
only "artist" exists, use that */
|
||||
for (unsigned i = 0; i < _tag.num_items; i++) {
|
||||
const TagItem &item = *_tag.items[i];
|
||||
for (const auto &item : _tag)
|
||||
if (item.type == TAG_ARTIST &&
|
||||
StringMatch(item.value))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,9 +47,7 @@ void tag_print(Client &client, const Tag &tag)
|
|||
if (tag.time >= 0)
|
||||
client_printf(client, SONG_TIME "%i\n", tag.time);
|
||||
|
||||
for (unsigned i = 0; i < tag.num_items; i++) {
|
||||
for (const auto &i : tag)
|
||||
client_printf(client, "%s: %s\n",
|
||||
tag_item_names[tag.items[i]->type],
|
||||
tag.items[i]->value);
|
||||
}
|
||||
tag_item_names[i.type], i.value);
|
||||
}
|
||||
|
|
|
@ -32,8 +32,7 @@ tag_save(FILE *file, const Tag &tag)
|
|||
if (tag.has_playlist)
|
||||
fprintf(file, "Playlist: yes\n");
|
||||
|
||||
for (unsigned i = 0; i < tag.num_items; i++)
|
||||
for (const auto &i : tag)
|
||||
fprintf(file, "%s: %s\n",
|
||||
tag_item_names[tag.items[i]->type],
|
||||
tag.items[i]->value);
|
||||
tag_item_names[i.type], i.value);
|
||||
}
|
||||
|
|
|
@ -73,9 +73,7 @@ static bool
|
|||
CollectGroupCounts(TagCountMap &map, TagType group, const Tag &tag)
|
||||
{
|
||||
bool found = false;
|
||||
for (unsigned i = 0; i < tag.num_items; ++i) {
|
||||
const TagItem &item = *tag.items[i];
|
||||
|
||||
for (const auto &item : tag) {
|
||||
if (item.type == group) {
|
||||
auto r = map.insert(std::make_pair(item.value,
|
||||
SearchStats()));
|
||||
|
|
|
@ -184,12 +184,10 @@ PrintUniqueTag(Client &client, TagType tag_type,
|
|||
assert(value != nullptr);
|
||||
client_printf(client, "%s: %s\n", tag_item_names[tag_type], value);
|
||||
|
||||
for (unsigned i = 0, n = tag.num_items; i < n; i++) {
|
||||
const TagItem &item = *tag.items[i];
|
||||
for (const auto &item : tag)
|
||||
if (item.type != tag_type)
|
||||
client_printf(client, "%s: %s\n",
|
||||
tag_item_names[item.type], item.value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -43,9 +43,7 @@ StatsVisitTag(DatabaseStats &stats, StringSet &artists, StringSet &albums,
|
|||
if (tag.time > 0)
|
||||
stats.total_duration += tag.time;
|
||||
|
||||
for (unsigned i = 0; i < tag.num_items; ++i) {
|
||||
const TagItem &item = *tag.items[i];
|
||||
|
||||
for (const auto &item : tag) {
|
||||
switch (item.type) {
|
||||
case TAG_ARTIST:
|
||||
#if defined(__clang__) || GCC_CHECK_VERSION(4,8)
|
||||
|
|
|
@ -272,8 +272,7 @@ vorbis_encoder_pre_tag(Encoder *_encoder, gcc_unused Error &error)
|
|||
static void
|
||||
copy_tag_to_vorbis_comment(vorbis_comment *vc, const Tag *tag)
|
||||
{
|
||||
for (unsigned i = 0; i < tag->num_items; i++) {
|
||||
const TagItem &item = *tag->items[i];
|
||||
for (const auto &item : *tag) {
|
||||
char *name = g_ascii_strup(tag_item_names[item.type], -1);
|
||||
vorbis_comment_add_tag(vc, name, item.value);
|
||||
g_free(name);
|
||||
|
|
|
@ -374,20 +374,22 @@ RoarOutput::SendTag(const Tag &tag)
|
|||
vals[0].key = const_cast<char *>("LENGTH");
|
||||
vals[0].value = timebuf;
|
||||
|
||||
for (unsigned i = 0; i < tag.num_items && cnt < 32; i++)
|
||||
{
|
||||
for (const auto &item : tag) {
|
||||
if (cnt >= 32)
|
||||
break;
|
||||
|
||||
bool is_uuid = false;
|
||||
const char *key = roar_tag_convert(tag.items[i]->type,
|
||||
const char *key = roar_tag_convert(item.type,
|
||||
&is_uuid);
|
||||
if (key != nullptr) {
|
||||
vals[cnt].key = const_cast<char *>(key);
|
||||
|
||||
if (is_uuid) {
|
||||
snprintf(uuid_buf[cnt], sizeof(uuid_buf[0]), "{UUID}%s",
|
||||
tag.items[i]->value);
|
||||
item.value);
|
||||
vals[cnt].value = uuid_buf[cnt];
|
||||
} else {
|
||||
vals[cnt].value = tag.items[i]->value;
|
||||
vals[cnt].value = const_cast<char *>(item.value);
|
||||
}
|
||||
|
||||
cnt++;
|
||||
|
|
|
@ -470,13 +470,13 @@ shout_tag_to_metadata(const Tag *tag, char *dest, size_t size)
|
|||
artist[0] = 0;
|
||||
title[0] = 0;
|
||||
|
||||
for (unsigned i = 0; i < tag->num_items; i++) {
|
||||
switch (tag->items[i]->type) {
|
||||
for (const auto &item : *tag) {
|
||||
switch (item.type) {
|
||||
case TAG_ARTIST:
|
||||
strncpy(artist, tag->items[i]->value, size);
|
||||
strncpy(artist, item.value, size);
|
||||
break;
|
||||
case TAG_TITLE:
|
||||
strncpy(title, tag->items[i]->value, size);
|
||||
strncpy(title, item.value, size);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -30,10 +30,10 @@ CopyTagItem(TagBuilder &dest, TagType dest_type,
|
|||
const Tag &src, TagType src_type)
|
||||
{
|
||||
bool found = false;
|
||||
const unsigned n = src.num_items;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
if (src.items[i]->type == src_type) {
|
||||
dest.AddItem(dest_type, src.items[i]->value);
|
||||
|
||||
for (const auto &item : src) {
|
||||
if (item.type == src_type) {
|
||||
dest.AddItem(dest_type, item.value);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
@ -87,11 +87,10 @@ TagSet::CheckUnique(TagType dest_type,
|
|||
uint32_t group_mask)
|
||||
{
|
||||
bool found = false;
|
||||
for (unsigned i = 0; i < tag.num_items; ++i) {
|
||||
if (tag.items[i]->type == src_type) {
|
||||
InsertUnique(tag, dest_type,
|
||||
tag.items[i]->value,
|
||||
group_mask);
|
||||
|
||||
for (const auto &item : tag) {
|
||||
if (item.type == src_type) {
|
||||
InsertUnique(tag, dest_type, item.value, group_mask);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,9 +118,9 @@ Tag::GetValue(TagType type) const
|
|||
{
|
||||
assert(type < TAG_NUM_OF_ITEM_TYPES);
|
||||
|
||||
for (unsigned i = 0; i < num_items; i++)
|
||||
if (items[i]->type == type)
|
||||
return items[i]->value;
|
||||
for (const auto &item : *this)
|
||||
if (item.type == type)
|
||||
return item.value;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "Compiler.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
|
@ -136,6 +137,59 @@ struct Tag {
|
|||
*/
|
||||
gcc_pure
|
||||
bool HasType(TagType type) const;
|
||||
|
||||
class const_iterator {
|
||||
friend struct Tag;
|
||||
const TagItem *const*cursor;
|
||||
|
||||
constexpr const_iterator(const TagItem *const*_cursor)
|
||||
:cursor(_cursor) {}
|
||||
|
||||
public:
|
||||
constexpr const TagItem &operator*() const {
|
||||
return **cursor;
|
||||
}
|
||||
|
||||
constexpr const TagItem *operator->() const {
|
||||
return *cursor;
|
||||
}
|
||||
|
||||
const_iterator &operator++() {
|
||||
++cursor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator++(int) {
|
||||
auto result = cursor++;
|
||||
return const_iterator{result};
|
||||
}
|
||||
|
||||
const_iterator &operator--() {
|
||||
--cursor;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const_iterator operator--(int) {
|
||||
auto result = cursor--;
|
||||
return const_iterator{result};
|
||||
}
|
||||
|
||||
constexpr bool operator==(const_iterator other) const {
|
||||
return cursor == other.cursor;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(const_iterator other) const {
|
||||
return cursor != other.cursor;
|
||||
}
|
||||
};
|
||||
|
||||
const_iterator begin() const {
|
||||
return const_iterator{items};
|
||||
}
|
||||
|
||||
const_iterator end() const {
|
||||
return const_iterator{items + num_items};
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -160,8 +160,7 @@ ToString(const Tag &tag)
|
|||
|
||||
std::string result = buffer;
|
||||
|
||||
for (unsigned i = 0, n = tag.num_items; i != n; ++i) {
|
||||
const TagItem &item = *tag.items[i];
|
||||
for (const auto &item : tag) {
|
||||
result.push_back('|');
|
||||
result.append(tag_item_names[item.type]);
|
||||
result.push_back('=');
|
||||
|
|
Loading…
Reference in New Issue