summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndrzej Rybczak <electricityispower@gmail.com>2015-04-13 01:43:07 +0200
committerAndrzej Rybczak <electricityispower@gmail.com>2015-04-18 17:41:10 +0200
commita21d9ca4250d93d12fb70bdf5a01169ec753e4b9 (patch)
treee7ceee4c4b39fed8bae8273f408d484962adf70e /src
parent4a372c0fbb130e8cb5b5a4bb200132c6928b4472 (diff)
format: split into two headers
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/display.cpp1
-rw-r--r--src/format.cpp2
-rw-r--r--src/format.h223
-rw-r--r--src/format_impl.h263
-rw-r--r--src/lyrics.cpp1
-rw-r--r--src/settings.cpp1
-rw-r--r--src/status.cpp1
-rw-r--r--src/utility/comparators.cpp1
9 files changed, 274 insertions, 220 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 4e4530b7..aa945017 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -73,6 +73,7 @@ noinst_HEADERS = \
display.h \
enums.h \
format.h \
+ format_impl.h \
global.h \
help.h \
helpers.h \
diff --git a/src/display.cpp b/src/display.cpp
index 83a1b3bf..6241068e 100644
--- a/src/display.cpp
+++ b/src/display.cpp
@@ -23,6 +23,7 @@
#include "browser.h"
#include "charset.h"
#include "display.h"
+#include "format_impl.h"
#include "helpers.h"
#include "song_info.h"
#include "playlist.h"
diff --git a/src/format.cpp b/src/format.cpp
index 329df462..b1924fce 100644
--- a/src/format.cpp
+++ b/src/format.cpp
@@ -20,7 +20,7 @@
#include <stdexcept>
-#include "format.h"
+#include "format_impl.h"
#include "utility/type_conversions.h"
namespace {
diff --git a/src/format.h b/src/format.h
index 378943e4..17cf23e0 100644
--- a/src/format.h
+++ b/src/format.h
@@ -25,9 +25,6 @@
#include "menu.h"
#include "song.h"
-#include "strbuffer.h"
-#include "utility/functional.h"
-#include "utility/wide_string.h"
namespace Format {
@@ -65,39 +62,6 @@ private:
enum class Result { Empty, Missing, Ok };
-// Commutative binary operation such that:
-// - Empty + Empty = Empty
-// - Empty + Missing = Missing
-// - Empty + Ok = Ok
-// - Missing + Missing = Missing
-// - Missing + Ok = Missing
-// - Ok + Ok = Ok
-inline Result &operator+=(Result &base, Result result)
-{
- if (base == Result::Missing || result == Result::Missing)
- base = Result::Missing;
- else if (base == Result::Ok || result == Result::Ok)
- base = Result::Ok;
- return base;
-}
-
-/*inline std::ostream &operator<<(std::ostream &os, Result r)
-{
- switch (r)
- {
- case Result::Empty:
- os << "empty";
- break;
- case Result::Missing:
- os << "missing";
- break;
- case Result::Ok:
- os << "ok";
- break;
- }
- return os;
-}*/
-
template <typename CharT>
using Expression = boost::variant<
std::basic_string<CharT>,
@@ -126,198 +90,19 @@ private:
Base m_base;
};
-template <typename CharT, typename OutputT, typename SecondOutputT = OutputT>
-struct Printer: boost::static_visitor<Result>
-{
- typedef std::basic_string<CharT> StringT;
-
- Printer(OutputT &os, const MPD::Song *song, SecondOutputT *second_os, const unsigned flags)
- : m_output(os)
- , m_song(song)
- , m_output_switched(false)
- , m_second_os(second_os)
- , m_no_output(0)
- , m_flags(flags)
- { }
-
- Result operator()(const StringT &s)
- {
- if (!s.empty())
- {
- output(s);
- return Result::Ok;
- }
- else
- return Result::Empty;
- }
-
- Result operator()(const NC::Color &c)
- {
- if (m_flags & Flags::Color)
- output(c);
- return Result::Empty;
- }
-
- Result operator()(NC::Format fmt)
- {
- if (m_flags & Flags::Format)
- output(fmt);
- return Result::Empty;
- }
-
- Result operator()(OutputSwitch)
- {
- if (!m_no_output)
- m_output_switched = true;
- return Result::Ok;
- }
-
- Result operator()(const SongTag &st)
- {
- StringT tags;
- if (m_flags & Flags::Tag && m_song != nullptr)
- {
- tags = convertString<CharT, char>::apply(
- m_song->getTags(st.function())
- );
- }
- if (!tags.empty())
- {
- if (st.delimiter() > 0)
- {
- // shorten length by chopping off the tail
- if (st.function() == &MPD::Song::getLength)
- tags.resize(st.delimiter());
- else
- tags = wideShorten(tags, st.delimiter());
- }
- output(tags);
- return Result::Ok;
- }
- else
- return Result::Missing;
- }
-
- // If all Empty -> Empty, if any Ok -> continue with Ok, if any Missing -> stop with Empty.
- Result operator()(const Group<CharT> &group)
- {
- auto visit = [this, &group] {
- Result result = Result::Empty;
- for (const auto &ex : group.base())
- {
- result += boost::apply_visitor(*this, ex);
- if (result == Result::Missing)
- {
- result = Result::Empty;
- break;
- }
- }
- return result;
- };
-
- ++m_no_output;
- Result result = visit();
- --m_no_output;
- if (!m_no_output && result == Result::Ok)
- visit();
- return result;
- }
-
- // If all Empty or Missing -> Empty, if any Ok -> stop with Ok.
- Result operator()(const FirstOf<CharT> &first_of)
- {
- for (const auto &ex : first_of.base())
- {
- if (boost::apply_visitor(*this, ex) == Result::Ok)
- return Result::Ok;
- }
- return Result::Empty;
- }
-
-private:
- // generic version for streams (buffers, menus)
- template <typename ValueT, typename OutputStreamT>
- struct output_ {
- static void exec(OutputStreamT &os, const ValueT &value) {
- os << value;
- }
- };
- // specialization for strings (input/output)
- template <typename SomeCharT, typename OtherCharT>
- struct output_<std::basic_string<SomeCharT>, std::basic_string<OtherCharT>> {
- typedef std::basic_string<SomeCharT> SomeString;
- typedef std::basic_string<OtherCharT> OtherString;
-
- // compile only if string types are the same
- static typename std::enable_if<
- std::is_same<SomeString, OtherString>::value,
- void
- >::type exec(SomeString &result, const OtherString &s) {
- result += s;
- }
- };
- // when writing to a string, we should ignore all other
- // properties. if this code is reached, throw an exception.
- template <typename ValueT, typename SomeCharT>
- struct output_<ValueT, std::basic_string<SomeCharT>> {
- static void exec(std::basic_string<CharT> &, const ValueT &) {
- throw std::logic_error("non-string property can't be appended to the string");
- }
- };
-
- template <typename ValueT>
- void output(const ValueT &value) const
- {
- if (!m_no_output)
- {
- if (m_output_switched && m_second_os != nullptr)
- output_<ValueT, SecondOutputT>::exec(*m_second_os, value);
- else
- output_<ValueT, OutputT>::exec(m_output, value);
- }
- }
-
- OutputT &m_output;
- const MPD::Song *m_song;
-
- bool m_output_switched;
- SecondOutputT *m_second_os;
-
- unsigned m_no_output;
- const unsigned m_flags;
-};
-
template <typename CharT, typename VisitorT>
-void visit(VisitorT &visitor, const AST<CharT> &ast)
-{
- for (const auto &ex : ast.base())
- boost::apply_visitor(visitor, ex);
-}
+void visit(VisitorT &visitor, const AST<CharT> &ast);
template <typename CharT, typename ItemT>
void print(const AST<CharT> &ast, NC::Menu<ItemT> &menu, const MPD::Song *song,
- NC::BasicBuffer<CharT> *buffer, const unsigned flags = Flags::All)
-{
- Printer<CharT, NC::Menu<ItemT>, NC::Buffer> printer(menu, song, buffer, flags);
- visit(printer, ast);
-}
+ NC::BasicBuffer<CharT> *buffer, const unsigned flags = Flags::All);
template <typename CharT>
void print(const AST<CharT> &ast, NC::BasicBuffer<CharT> &buffer,
- const MPD::Song *song, const unsigned flags = Flags::All)
-{
- Printer<CharT, NC::BasicBuffer<CharT>> printer(buffer, song, &buffer, flags);
- visit(printer, ast);
-}
+ const MPD::Song *song, const unsigned flags = Flags::All);
template <typename CharT>
-std::basic_string<CharT> stringify(const AST<CharT> &ast, const MPD::Song *song)
-{
- std::basic_string<CharT> result;
- Printer<CharT, std::basic_string<CharT>> printer(result, song, &result, Flags::Tag);
- visit(printer, ast);
- return result;
-}
+std::basic_string<CharT> stringify(const AST<CharT> &ast, const MPD::Song *song);
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);
diff --git a/src/format_impl.h b/src/format_impl.h
new file mode 100644
index 00000000..ec9ad973
--- /dev/null
+++ b/src/format_impl.h
@@ -0,0 +1,263 @@
+/***************************************************************************
+ * Copyright (C) 2008-2014 by Andrzej Rybczak *
+ * electricityispower@gmail.com *
+ * *
+ * 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 St, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef NCMPCPP_HAVE_FORMAT_IMPL_H
+#define NCMPCPP_HAVE_FORMAT_IMPL_H
+
+#include <boost/variant.hpp>
+
+#include "format.h"
+#include "menu.h"
+#include "song.h"
+#include "strbuffer.h"
+#include "utility/functional.h"
+#include "utility/wide_string.h"
+
+namespace Format {
+
+// Commutative binary operation such that:
+// - Empty + Empty = Empty
+// - Empty + Missing = Missing
+// - Empty + Ok = Ok
+// - Missing + Missing = Missing
+// - Missing + Ok = Missing
+// - Ok + Ok = Ok
+inline Result &operator+=(Result &base, Result result)
+{
+ if (base == Result::Missing || result == Result::Missing)
+ base = Result::Missing;
+ else if (base == Result::Ok || result == Result::Ok)
+ base = Result::Ok;
+ return base;
+}
+
+/*inline std::ostream &operator<<(std::ostream &os, Result r)
+{
+ switch (r)
+ {
+ case Result::Empty:
+ os << "empty";
+ break;
+ case Result::Missing:
+ os << "missing";
+ break;
+ case Result::Ok:
+ os << "ok";
+ break;
+ }
+ return os;
+}*/
+
+template <typename CharT, typename OutputT, typename SecondOutputT = OutputT>
+struct Printer: boost::static_visitor<Result>
+{
+ typedef std::basic_string<CharT> StringT;
+
+ Printer(OutputT &os, const MPD::Song *song, SecondOutputT *second_os, const unsigned flags)
+ : m_output(os)
+ , m_song(song)
+ , m_output_switched(false)
+ , m_second_os(second_os)
+ , m_no_output(0)
+ , m_flags(flags)
+ { }
+
+ Result operator()(const StringT &s)
+ {
+ if (!s.empty())
+ {
+ output(s);
+ return Result::Ok;
+ }
+ else
+ return Result::Empty;
+ }
+
+ Result operator()(const NC::Color &c)
+ {
+ if (m_flags & Flags::Color)
+ output(c);
+ return Result::Empty;
+ }
+
+ Result operator()(NC::Format fmt)
+ {
+ if (m_flags & Flags::Format)
+ output(fmt);
+ return Result::Empty;
+ }
+
+ Result operator()(OutputSwitch)
+ {
+ if (!m_no_output)
+ m_output_switched = true;
+ return Result::Ok;
+ }
+
+ Result operator()(const SongTag &st)
+ {
+ StringT tags;
+ if (m_flags & Flags::Tag && m_song != nullptr)
+ {
+ tags = convertString<CharT, char>::apply(
+ m_song->getTags(st.function())
+ );
+ }
+ if (!tags.empty())
+ {
+ if (st.delimiter() > 0)
+ {
+ // shorten length by chopping off the tail
+ if (st.function() == &MPD::Song::getLength)
+ tags.resize(st.delimiter());
+ else
+ tags = wideShorten(tags, st.delimiter());
+ }
+ output(tags);
+ return Result::Ok;
+ }
+ else
+ return Result::Missing;
+ }
+
+ // If all Empty -> Empty, if any Ok -> continue with Ok, if any Missing -> stop with Empty.
+ Result operator()(const Group<CharT> &group)
+ {
+ auto visit = [this, &group] {
+ Result result = Result::Empty;
+ for (const auto &ex : group.base())
+ {
+ result += boost::apply_visitor(*this, ex);
+ if (result == Result::Missing)
+ {
+ result = Result::Empty;
+ break;
+ }
+ }
+ return result;
+ };
+
+ ++m_no_output;
+ Result result = visit();
+ --m_no_output;
+ if (!m_no_output && result == Result::Ok)
+ visit();
+ return result;
+ }
+
+ // If all Empty or Missing -> Empty, if any Ok -> stop with Ok.
+ Result operator()(const FirstOf<CharT> &first_of)
+ {
+ for (const auto &ex : first_of.base())
+ {
+ if (boost::apply_visitor(*this, ex) == Result::Ok)
+ return Result::Ok;
+ }
+ return Result::Empty;
+ }
+
+private:
+ // generic version for streams (buffers, menus)
+ template <typename ValueT, typename OutputStreamT>
+ struct output_ {
+ static void exec(OutputStreamT &os, const ValueT &value) {
+ os << value;
+ }
+ };
+ // specialization for strings (input/output)
+ template <typename SomeCharT, typename OtherCharT>
+ struct output_<std::basic_string<SomeCharT>, std::basic_string<OtherCharT>> {
+ typedef std::basic_string<SomeCharT> SomeString;
+ typedef std::basic_string<OtherCharT> OtherString;
+
+ // compile only if string types are the same
+ static typename std::enable_if<
+ std::is_same<SomeString, OtherString>::value,
+ void
+ >::type exec(SomeString &result, const OtherString &s) {
+ result += s;
+ }
+ };
+ // when writing to a string, we should ignore all other
+ // properties. if this code is reached, throw an exception.
+ template <typename ValueT, typename SomeCharT>
+ struct output_<ValueT, std::basic_string<SomeCharT>> {
+ static void exec(std::basic_string<CharT> &, const ValueT &) {
+ throw std::logic_error("non-string property can't be appended to the string");
+ }
+ };
+
+ template <typename ValueT>
+ void output(const ValueT &value) const
+ {
+ if (!m_no_output)
+ {
+ if (m_output_switched && m_second_os != nullptr)
+ output_<ValueT, SecondOutputT>::exec(*m_second_os, value);
+ else
+ output_<ValueT, OutputT>::exec(m_output, value);
+ }
+ }
+
+ OutputT &m_output;
+ const MPD::Song *m_song;
+
+ bool m_output_switched;
+ SecondOutputT *m_second_os;
+
+ unsigned m_no_output;
+ const unsigned m_flags;
+};
+
+template <typename CharT, typename VisitorT>
+void visit(VisitorT &visitor, const AST<CharT> &ast)
+{
+ for (const auto &ex : ast.base())
+ boost::apply_visitor(visitor, ex);
+}
+
+template <typename CharT, typename ItemT>
+void print(const AST<CharT> &ast, NC::Menu<ItemT> &menu, const MPD::Song *song,
+ NC::BasicBuffer<CharT> *buffer, const unsigned flags)
+{
+ Printer<CharT, NC::Menu<ItemT>, NC::Buffer> printer(menu, song, buffer, flags);
+ visit(printer, ast);
+}
+
+template <typename CharT>
+void print(const AST<CharT> &ast, NC::BasicBuffer<CharT> &buffer,
+ const MPD::Song *song, const unsigned flags)
+{
+ Printer<CharT, NC::BasicBuffer<CharT>> printer(buffer, song, &buffer, flags);
+ visit(printer, ast);
+}
+
+template <typename CharT>
+std::basic_string<CharT> stringify(const AST<CharT> &ast, const MPD::Song *song)
+{
+ std::basic_string<CharT> result;
+ Printer<CharT, std::basic_string<CharT>> printer(result, song, &result, Flags::Tag);
+ visit(printer, ast);
+ return result;
+}
+
+}
+
+#endif // NCMPCPP_HAVE_FORMAT__IMPL_H
diff --git a/src/lyrics.cpp b/src/lyrics.cpp
index b8db4287..7f470c13 100644
--- a/src/lyrics.cpp
+++ b/src/lyrics.cpp
@@ -26,6 +26,7 @@
#include "browser.h"
#include "charset.h"
#include "curl_handle.h"
+#include "format_impl.h"
#include "global.h"
#include "helpers.h"
#include "lyrics.h"
diff --git a/src/settings.cpp b/src/settings.cpp
index a42dbc35..77c2e31f 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -23,6 +23,7 @@
#include <stdexcept>
#include "configuration.h"
+#include "format_impl.h"
#include "helpers.h"
#include "settings.h"
#include "utility/conversion.h"
diff --git a/src/status.cpp b/src/status.cpp
index 51ede82e..8db7a6d6 100644
--- a/src/status.cpp
+++ b/src/status.cpp
@@ -24,6 +24,7 @@
#include "browser.h"
#include "charset.h"
+#include "format_impl.h"
#include "global.h"
#include "helpers.h"
#include "lyrics.h"
diff --git a/src/utility/comparators.cpp b/src/utility/comparators.cpp
index 85ada86f..533cd389 100644
--- a/src/utility/comparators.cpp
+++ b/src/utility/comparators.cpp
@@ -20,6 +20,7 @@
#include <locale>
#include "comparators.h"
+#include "format_impl.h"
#include "utility/string.h"
namespace {