Make it easier to customize getting internal values

This commit is contained in:
Martchus 2021-01-30 19:12:04 +01:00
parent 65d52b2d57
commit 7692eec9af
3 changed files with 24 additions and 16 deletions

View File

@ -68,6 +68,7 @@ protected:
using CRTPBase = FieldMapBasedTag<ImplementationType>;
const TagValue &internallyGetValue(const IdentifierType &id) const;
void internallyGetValuesFromField(const FieldType &field, std::vector<const TagValue *> &values) const;
std::vector<const TagValue *> internallyGetValues(const IdentifierType &id) const;
bool internallySetValue(const IdentifierType &id, const TagValue &value);
bool internallySetValues(const IdentifierType &id, const std::vector<TagValue> &values);
@ -126,6 +127,19 @@ template <class ImplementationType> const TagValue &FieldMapBasedTag<Implementat
return i != m_fields.end() ? i->second.value() : TagValue::empty();
}
/*!
* \brief Default way to gather values from a field in internallyGetValues().
* \remarks Shadow in subclass to provide custom implementation.
*/
template <class ImplementationType>
void FieldMapBasedTag<ImplementationType>::internallyGetValuesFromField(
const FieldMapBasedTag<ImplementationType>::FieldType &field, std::vector<const TagValue *> &values) const
{
if (!field.value().isEmpty()) {
values.emplace_back(&field.value());
}
}
/*!
* \brief Default implementation for values().
* \remarks Shadow in subclass to provide custom implementation.
@ -136,9 +150,7 @@ std::vector<const TagValue *> FieldMapBasedTag<ImplementationType>::internallyGe
auto range = m_fields.equal_range(id);
std::vector<const TagValue *> values;
for (auto i = range.first; i != range.second; ++i) {
if (!i->second.value().isEmpty()) {
values.push_back(&i->second.value());
}
static_cast<const ImplementationType *>(this)->internallyGetValuesFromField(i->second, values);
}
return values;
}

View File

@ -68,22 +68,18 @@ void Id3v2Tag::ensureTextValuesAreProperlyEncoded()
}
/*!
* \brief Works like the default implementation but adds additional values as well.
* \brief Adds additional values as well.
*/
std::vector<const TagValue *> Id3v2Tag::internallyGetValues(const IdentifierType &id) const
void Id3v2Tag::internallyGetValuesFromField(const Id3v2Tag::FieldType &field, std::vector<const TagValue *> &values) const
{
auto range = fields().equal_range(id);
std::vector<const TagValue *> values;
for (auto i = range.first; i != range.second; ++i) {
const auto &frame(i->second);
if (!frame.value().isEmpty()) {
values.push_back(&frame.value());
}
for (const auto &value : frame.additionalValues()) {
values.push_back(&value);
if (!field.value().isEmpty()) {
values.emplace_back(&field.value());
}
for (const auto &value : field.additionalValues()) {
if (!value.isEmpty()) {
values.emplace_back(&value);
}
}
return values;
}
/*!

View File

@ -95,7 +95,7 @@ protected:
IdentifierType internallyGetFieldId(KnownField field) const;
KnownField internallyGetKnownField(const IdentifierType &id) const;
TagDataType internallyGetProposedDataType(const std::uint32_t &id) const;
std::vector<const TagValue *> internallyGetValues(const IdentifierType &id) const;
void internallyGetValuesFromField(const FieldType &field, std::vector<const TagValue *> &values) const;
bool internallySetValues(const IdentifierType &id, const std::vector<TagValue> &values);
private: