From 41a7203c28d2cc7550f1bb05f767950d388326cd Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 12 Jul 2014 17:22:39 +0200 Subject: Tag: add class const_iterator and methods begin(), end() Enables using range-based "for". --- src/tag/Set.cxx | 17 ++++++++--------- src/tag/Tag.cxx | 6 +++--- src/tag/Tag.hxx | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 12 deletions(-) (limited to 'src/tag') diff --git a/src/tag/Set.cxx b/src/tag/Set.cxx index 59f66bf84..47a8423bf 100644 --- a/src/tag/Set.cxx +++ b/src/tag/Set.cxx @@ -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; } } diff --git a/src/tag/Tag.cxx b/src/tag/Tag.cxx index 448f3b26a..1b338ae8d 100644 --- a/src/tag/Tag.cxx +++ b/src/tag/Tag.cxx @@ -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; } diff --git a/src/tag/Tag.hxx b/src/tag/Tag.hxx index 5d3aaad0c..74221417f 100644 --- a/src/tag/Tag.hxx +++ b/src/tag/Tag.hxx @@ -25,6 +25,7 @@ #include "Compiler.h" #include +#include #include @@ -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}; + } }; /** -- cgit v1.2.3