diff --git a/Makefile.am b/Makefile.am index ca800617a..f746d25aa 100644 --- a/Makefile.am +++ b/Makefile.am @@ -977,6 +977,7 @@ libtag_a_SOURCES =\ src/tag/TagItem.hxx \ src/tag/TagHandler.cxx src/tag/TagHandler.hxx \ src/tag/Mask.hxx \ + src/tag/Fallback.hxx \ src/tag/Settings.cxx src/tag/Settings.hxx \ src/tag/TagConfig.cxx src/tag/TagConfig.hxx \ src/tag/TagNames.c \ diff --git a/src/tag/Fallback.hxx b/src/tag/Fallback.hxx new file mode 100644 index 000000000..5c75e8bee --- /dev/null +++ b/src/tag/Fallback.hxx @@ -0,0 +1,43 @@ +/* + * Copyright 2003-2018 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_TAG_FALLBACK_HXX +#define MPD_TAG_FALLBACK_HXX + +#include + +template +bool +ApplyTagFallback(TagType type, F &&f) noexcept +{ + if (type == TAG_ALBUM_ARTIST) + /* fall back to "Artist" if no "AlbumArtist" was found */ + return f(TAG_ARTIST); + + return false; +} + +template +bool +ApplyTagWithFallback(TagType type, F &&f) noexcept +{ + return f(type) || ApplyTagFallback(type, std::forward(f)); +} + +#endif diff --git a/src/tag/Set.cxx b/src/tag/Set.cxx index fa4ecaf65..d52d517aa 100644 --- a/src/tag/Set.cxx +++ b/src/tag/Set.cxx @@ -18,17 +18,20 @@ */ #include "Set.hxx" +#include "Fallback.hxx" #include "TagBuilder.hxx" #include "util/StringView.hxx" +#include + #include /** * Copy all tag items of the specified type. */ static bool -CopyTagItem(TagBuilder &dest, TagType dest_type, - const Tag &src, TagType src_type) +CopyTagItem2(TagBuilder &dest, TagType dest_type, + const Tag &src, TagType src_type) { bool found = false; @@ -49,9 +52,9 @@ CopyTagItem(TagBuilder &dest, TagType dest_type, static void CopyTagItem(TagBuilder &dest, const Tag &src, TagType type) { - if (!CopyTagItem(dest, type, src, type) && - type == TAG_ALBUM_ARTIST) - CopyTagItem(dest, type, src, TAG_ARTIST); + ApplyTagWithFallback(type, + std::bind(CopyTagItem2, std::ref(dest), type, + std::cref(src), std::placeholders::_1)); } /** @@ -105,9 +108,10 @@ TagSet::InsertUnique(const Tag &tag, assert((group_mask & (tag_mask_t(1) << unsigned(type))) == 0); - if (!CheckUnique(type, tag, type, group_mask) && - (type != TAG_ALBUM_ARTIST || - /* fall back to "Artist" if no "AlbumArtist" was found */ - !CheckUnique(type, tag, TAG_ARTIST, group_mask))) + if (!ApplyTagWithFallback(type, + std::bind(&TagSet::CheckUnique, this, + type, std::cref(tag), + std::placeholders::_1, + group_mask))) InsertUnique(tag, type, "", group_mask); }