Rename SongTagMap to TagVector and allow it to store regular string chunks

This commit is contained in:
Andrzej Rybczak
2017-03-27 13:08:27 +02:00
parent 0185ee7fa4
commit a22bad7ad5
2 changed files with 33 additions and 19 deletions

View File

@@ -60,10 +60,18 @@ private:
unsigned m_delimiter; unsigned m_delimiter;
}; };
inline bool operator==(const SongTag &lhs, const SongTag &rhs) {
return lhs.function() == rhs.function()
&& lhs.delimiter() == rhs.delimiter();
}
inline bool operator!=(const SongTag &lhs, const SongTag &rhs) {
return !(lhs == rhs);
}
template <typename CharT> template <typename CharT>
using SongTagMap = std::vector< using TagVector = std::vector<
std::pair< std::pair<
SongTag, boost::optional<SongTag>,
std::basic_string<CharT> std::basic_string<CharT>
> >
>; >;
@@ -112,6 +120,9 @@ void print(const AST<CharT> &ast, NC::BasicBuffer<CharT> &buffer,
template <typename CharT> template <typename CharT>
std::basic_string<CharT> stringify(const AST<CharT> &ast, const MPD::Song *song); std::basic_string<CharT> stringify(const AST<CharT> &ast, const MPD::Song *song);
template <typename CharT>
TagVector<CharT> flatten(const AST<CharT> &ast, const MPD::Song &song);
AST<char> parse(const std::string &s, const unsigned flags = Flags::All); AST<char> parse(const std::string &s, const unsigned flags = Flags::All);
AST<wchar_t> parse(const std::wstring &ws, const unsigned flags = Flags::All); AST<wchar_t> parse(const std::wstring &ws, const unsigned flags = Flags::All);

View File

@@ -125,7 +125,8 @@ struct Printer: boost::static_visitor<Result>
if (st.delimiter() > 0) if (st.delimiter() > 0)
{ {
// shorten date/length by simple truncation // shorten date/length by simple truncation
if (st.function() == &MPD::Song::getDate || st.function() == &MPD::Song::getLength) if (st.function() == &MPD::Song::getDate
|| st.function() == &MPD::Song::getLength)
tags.resize(st.delimiter()); tags.resize(st.delimiter());
else else
tags = wideShorten(tags, st.delimiter()); tags = wideShorten(tags, st.delimiter());
@@ -137,7 +138,8 @@ struct Printer: boost::static_visitor<Result>
return Result::Missing; return Result::Missing;
} }
// If all Empty -> Empty, if any Ok -> continue with Ok, if any Missing -> stop with Empty. // If all Empty -> Empty, if any Ok -> continue with Ok, if any Missing ->
// stop with Empty.
Result operator()(const Group<CharT> &group) Result operator()(const Group<CharT> &group)
{ {
auto visit = [this, &group] { auto visit = [this, &group] {
@@ -196,8 +198,8 @@ private:
result += s; result += s;
} }
}; };
// when writing to a string, we should ignore all other // When writing to a string, we should ignore all other properties. If this
// properties. if this code is reached, throw an exception. // code is reached, throw an exception.
template <typename ValueT, typename SomeCharT> template <typename ValueT, typename SomeCharT>
struct output_<ValueT, std::basic_string<SomeCharT>> { struct output_<ValueT, std::basic_string<SomeCharT>> {
static void exec(std::basic_string<CharT> &, const ValueT &, const SongTag *) { static void exec(std::basic_string<CharT> &, const ValueT &, const SongTag *) {
@@ -205,26 +207,27 @@ private:
} }
}; };
// Specialization for SongTagMap. // Specialization for TagVector.
template <typename SomeCharT, typename OtherCharT> template <typename SomeCharT, typename OtherCharT>
struct output_<std::basic_string<SomeCharT>, SongTagMap<OtherCharT> > { struct output_<std::basic_string<SomeCharT>, TagVector<OtherCharT> > {
// Compile only if string types are the same. // Compile only if string types are the same.
static typename std::enable_if< static typename std::enable_if<
std::is_same<SomeCharT, OtherCharT>::value, std::is_same<SomeCharT, OtherCharT>::value,
void void
>::type exec(SongTagMap<OtherCharT> &acc, >::type exec(TagVector<OtherCharT> &acc,
const std::basic_string<SomeCharT> &s, const SongTag *st) { const std::basic_string<SomeCharT> &s, const SongTag *st) {
if (st != nullptr) { if (st != nullptr)
acc.emplace_back(*st, s); acc.emplace_back(*st, s);
} else
acc.emplace_back(boost::none, s);
} }
}; };
// When extracting tags from a song all the other properties should // When extracting tags from a song all the other properties should be
// be ignored. If that's not the case, throw an exception. // ignored. If that's not the case, throw an exception.
template <typename ValueT, typename SomeCharT> template <typename ValueT, typename SomeCharT>
struct output_<ValueT, SongTagMap<SomeCharT> > { struct output_<ValueT, TagVector<SomeCharT> > {
static void exec(SongTagMap<SomeCharT> &, const ValueT &, const SongTag *) { static void exec(TagVector<SomeCharT> &, const ValueT &, const SongTag *) {
throw std::logic_error("Non-string property can't be inserted into the SongTagMap"); throw std::logic_error("Non-string property can't be inserted into the TagVector");
} }
}; };
@@ -283,10 +286,10 @@ std::basic_string<CharT> stringify(const AST<CharT> &ast, const MPD::Song *song)
} }
template <typename CharT> template <typename CharT>
SongTagMap<CharT> extractTags(const AST<CharT> &ast, const MPD::Song &song) TagVector<CharT> flatten(const AST<CharT> &ast, const MPD::Song &song)
{ {
SongTagMap<CharT> result; TagVector<CharT> result;
Printer<CharT, SongTagMap<CharT> > printer(result, &song, &result, Flags::Tag); Printer<CharT, TagVector<CharT>> printer(result, &song, &result, Flags::Tag);
visit(printer, ast); visit(printer, ast);
return result; return result;
} }