song list: get rid of boost::zip_iterator and improve {Const,}SongIterator
This commit is contained in:
@@ -59,6 +59,7 @@ ncmpcpp_LDFLAGS = $(all_libraries)
|
||||
noinst_HEADERS = \
|
||||
helpers/song_iterator_maker.h \
|
||||
utility/comparators.h \
|
||||
utility/const.h \
|
||||
utility/conversion.h \
|
||||
utility/functional.h \
|
||||
utility/html.h \
|
||||
|
||||
@@ -80,9 +80,9 @@ std::vector<std::shared_ptr<Actions::BaseAction>> AvailableActions;
|
||||
|
||||
void populateActions();
|
||||
|
||||
bool scrollTagCanBeRun(NC::List *&list, SongList *&songs);
|
||||
void scrollTagUpRun(NC::List *list, SongList *songs, MPD::Song::GetFunction get);
|
||||
void scrollTagDownRun(NC::List *list, SongList *songs, MPD::Song::GetFunction get);
|
||||
bool scrollTagCanBeRun(NC::List *&list, const SongList *&songs);
|
||||
void scrollTagUpRun(NC::List *list, const SongList *songs, MPD::Song::GetFunction get);
|
||||
void scrollTagDownRun(NC::List *list, const SongList *songs, MPD::Song::GetFunction get);
|
||||
|
||||
void seek();
|
||||
void findItem(const SearchDirection direction);
|
||||
@@ -1783,28 +1783,25 @@ bool SelectAlbum::canBeRun()
|
||||
void SelectAlbum::run()
|
||||
{
|
||||
const auto front = m_songs->beginS(), current = m_songs->currentS(), end = m_songs->endS();
|
||||
auto *s = current->get<Bit::Song>();
|
||||
if (s == nullptr)
|
||||
if (current->song() == nullptr)
|
||||
return;
|
||||
auto get = &MPD::Song::getAlbum;
|
||||
const std::string tag = s->getTags(get);
|
||||
const std::string tag = current->song()->getTags(get);
|
||||
// go up
|
||||
for (auto it = current; it != front;)
|
||||
{
|
||||
--it;
|
||||
s = it->get<Bit::Song>();
|
||||
if (s == nullptr || s->getTags(get) != tag)
|
||||
if (it->song() == nullptr || it->song()->getTags(get) != tag)
|
||||
break;
|
||||
it->get<Bit::Properties>().setSelected(true);
|
||||
it->properties().setSelected(true);
|
||||
}
|
||||
// go down
|
||||
for (auto it = current;;)
|
||||
{
|
||||
it->get<Bit::Properties>().setSelected(true);
|
||||
it->properties().setSelected(true);
|
||||
if (++it == end)
|
||||
break;
|
||||
s = it->get<Bit::Song>();
|
||||
if (s == nullptr || s->getTags(get) != tag)
|
||||
if (it->song() == nullptr || it->song()->getTags(get) != tag)
|
||||
break;
|
||||
}
|
||||
Statusbar::print("Album around cursor position selected");
|
||||
@@ -2809,7 +2806,7 @@ void populateActions()
|
||||
}
|
||||
}
|
||||
|
||||
bool scrollTagCanBeRun(NC::List *&list, SongList *&songs)
|
||||
bool scrollTagCanBeRun(NC::List *&list, const SongList *&songs)
|
||||
{
|
||||
auto w = myScreen->activeWindow();
|
||||
if (list != static_cast<void *>(w))
|
||||
@@ -2820,36 +2817,34 @@ bool scrollTagCanBeRun(NC::List *&list, SongList *&songs)
|
||||
&& songs != nullptr;
|
||||
}
|
||||
|
||||
void scrollTagUpRun(NC::List *list, SongList *songs, MPD::Song::GetFunction get)
|
||||
void scrollTagUpRun(NC::List *list, const SongList *songs, MPD::Song::GetFunction get)
|
||||
{
|
||||
const auto front = songs->beginS();
|
||||
auto it = songs->currentS();
|
||||
if (auto *s = it->get<Bit::Song>())
|
||||
if (it->song() != nullptr)
|
||||
{
|
||||
const std::string tag = s->getTags(get);
|
||||
const std::string tag = it->song()->getTags(get);
|
||||
while (it != front)
|
||||
{
|
||||
--it;
|
||||
s = it->get<Bit::Song>();
|
||||
if (s == nullptr || s->getTags(get) != tag)
|
||||
if (it->song() == nullptr || it->song()->getTags(get) != tag)
|
||||
break;
|
||||
}
|
||||
list->highlight(it-front);
|
||||
}
|
||||
}
|
||||
|
||||
void scrollTagDownRun(NC::List *list, SongList *songs, MPD::Song::GetFunction get)
|
||||
void scrollTagDownRun(NC::List *list, const SongList *songs, MPD::Song::GetFunction get)
|
||||
{
|
||||
const auto front = songs->beginS(), back = --songs->endS();
|
||||
auto it = songs->currentS();
|
||||
if (auto *s = it->get<Bit::Song>())
|
||||
if (it->song() != nullptr)
|
||||
{
|
||||
const std::string tag = s->getTags(get);
|
||||
const std::string tag = it->song()->getTags(get);
|
||||
while (it != back)
|
||||
{
|
||||
++it;
|
||||
s = it->get<Bit::Song>();
|
||||
if (s == nullptr || s->getTags(get) != tag)
|
||||
if (it->song() == nullptr || it->song()->getTags(get) != tag)
|
||||
break;
|
||||
}
|
||||
list->highlight(it-front);
|
||||
@@ -2882,7 +2877,8 @@ void seek()
|
||||
// can be run and one of them is of the given type. This will still not work
|
||||
// in some contrived cases, but allows for more flexibility than accepting
|
||||
// single actions only.
|
||||
auto hasRunnableAction = [](BindingsConfiguration::BindingIteratorPair &bindings, Actions::Type type) {
|
||||
auto hasRunnableAction = [](BindingsConfiguration::BindingIteratorPair &bindings,
|
||||
Actions::Type type) {
|
||||
bool success = false;
|
||||
for (auto binding = bindings.first; binding != bindings.second; ++binding)
|
||||
{
|
||||
|
||||
@@ -280,7 +280,7 @@ private:
|
||||
virtual void run() override;
|
||||
|
||||
NC::List *m_list;
|
||||
SongList *m_songs;
|
||||
const SongList *m_songs;
|
||||
};
|
||||
|
||||
struct ScrollUpAlbum: BaseAction
|
||||
@@ -292,7 +292,7 @@ private:
|
||||
virtual void run() override;
|
||||
|
||||
NC::List *m_list;
|
||||
SongList *m_songs;
|
||||
const SongList *m_songs;
|
||||
};
|
||||
|
||||
struct ScrollDownArtist: BaseAction
|
||||
@@ -304,7 +304,7 @@ private:
|
||||
virtual void run() override;
|
||||
|
||||
NC::List *m_list;
|
||||
SongList *m_songs;
|
||||
const SongList *m_songs;
|
||||
};
|
||||
|
||||
struct ScrollDownAlbum: BaseAction
|
||||
@@ -316,7 +316,7 @@ private:
|
||||
virtual void run() override;
|
||||
|
||||
NC::List *m_list;
|
||||
SongList *m_songs;
|
||||
const SongList *m_songs;
|
||||
};
|
||||
|
||||
struct PageUp: BaseAction
|
||||
|
||||
@@ -70,54 +70,53 @@ void clearDirectory(const std::string &directory);
|
||||
std::string itemToString(const MPD::Item &item);
|
||||
bool browserEntryMatcher(const Regex::Regex &rx, const MPD::Item &item, bool filter);
|
||||
|
||||
template <bool Const>
|
||||
struct SongExtractor
|
||||
{
|
||||
typedef SongExtractor type;
|
||||
|
||||
typedef typename NC::Menu<MPD::Item>::Item MenuItem;
|
||||
typedef typename std::conditional<Const, const MenuItem, MenuItem>::type Item;
|
||||
typedef typename std::conditional<Const, const MPD::Song, MPD::Song>::type Song;
|
||||
|
||||
Song *operator()(Item &item) const
|
||||
{
|
||||
Song *ptr = nullptr;
|
||||
if (item.value().type() == MPD::Item::Type::Song)
|
||||
ptr = const_cast<Song *>(&item.value().song());
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
struct SongPropertiesExtractor<MPD::Item>
|
||||
{
|
||||
template <typename ItemT>
|
||||
auto &operator()(ItemT &item) const
|
||||
{
|
||||
auto s = item.value().type() == MPD::Item::Type::Song
|
||||
? &item.value().song()
|
||||
: nullptr;
|
||||
m_cache.assign(&item.properties(), s);
|
||||
return m_cache;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable SongProperties m_cache;
|
||||
};
|
||||
|
||||
SongIterator BrowserWindow::currentS()
|
||||
{
|
||||
return makeSongIterator_<MPD::Item>(current(), SongExtractor<false>());
|
||||
return makeSongIterator(current());
|
||||
}
|
||||
|
||||
ConstSongIterator BrowserWindow::currentS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::Item>(current(), SongExtractor<true>());
|
||||
return makeConstSongIterator(current());
|
||||
}
|
||||
|
||||
SongIterator BrowserWindow::beginS()
|
||||
{
|
||||
return makeSongIterator_<MPD::Item>(begin(), SongExtractor<false>());
|
||||
return makeSongIterator(begin());
|
||||
}
|
||||
|
||||
ConstSongIterator BrowserWindow::beginS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::Item>(begin(), SongExtractor<true>());
|
||||
return makeConstSongIterator(begin());
|
||||
}
|
||||
|
||||
SongIterator BrowserWindow::endS()
|
||||
{
|
||||
return makeSongIterator_<MPD::Item>(end(), SongExtractor<false>());
|
||||
return makeSongIterator(end());
|
||||
}
|
||||
|
||||
ConstSongIterator BrowserWindow::endS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::Item>(end(), SongExtractor<true>());
|
||||
return makeConstSongIterator(end());
|
||||
}
|
||||
|
||||
std::vector<MPD::Song> BrowserWindow::getSelectedSongs()
|
||||
|
||||
@@ -87,8 +87,7 @@ void setProperties(NC::Menu<T> &menu, const MPD::Song &s, const SongList &list,
|
||||
auto next = list.beginS() + drawn_pos + 1;
|
||||
if (next != list.endS())
|
||||
{
|
||||
auto next_s = next->get<Bit::Song>();
|
||||
if (next_s != nullptr && next_s->getAlbum() != s.getAlbum())
|
||||
if (next->song() != nullptr && next->song()->getAlbum() != s.getAlbum())
|
||||
separate_albums = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ const MPD::Song *currentSong(const BaseScreen *screen)
|
||||
{
|
||||
const auto it = list->currentS();
|
||||
if (it != list->endS())
|
||||
ptr = it->get<Bit::Song>();
|
||||
ptr = it->song();
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
@@ -387,12 +387,10 @@ template <typename ListT>
|
||||
void markSongsInPlaylist(ListT &list)
|
||||
{
|
||||
ScopedUnfilteredMenu<typename ListT::Item::Type> sunfilter(ReapplyFilter::No, list);
|
||||
MPD::Song *s;
|
||||
for (auto &p : static_cast<SongList &>(list))
|
||||
{
|
||||
s = p.get<Bit::Song>();
|
||||
if (s != nullptr)
|
||||
p.get<Bit::Properties>().setBold(myPlaylist->checkForSong(*s));
|
||||
if (p.song() != nullptr)
|
||||
p.properties().setBold(myPlaylist->checkForSong(*p.song()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,26 +22,48 @@
|
||||
#define NCMPCPP_HELPERS_SONG_ITERATOR_MAKER_H
|
||||
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/zip_iterator.hpp>
|
||||
#include "menu.h"
|
||||
#include "song_list.h"
|
||||
|
||||
template <typename ItemT, typename TransformT>
|
||||
SongIterator makeSongIterator_(typename NC::Menu<ItemT>::Iterator it, TransformT &&map)
|
||||
template <typename SongT>
|
||||
struct SongPropertiesExtractor
|
||||
{
|
||||
return SongIterator(boost::make_zip_iterator(boost::make_tuple(
|
||||
typename NC::Menu<ItemT>::PropertiesIterator(it),
|
||||
boost::make_transform_iterator(it, std::forward<TransformT>(map))
|
||||
)));
|
||||
template <typename ItemT>
|
||||
auto &operator()(ItemT &item) const
|
||||
{
|
||||
return m_cache.assign(&item.properties(), &item.value());
|
||||
}
|
||||
|
||||
private:
|
||||
mutable SongProperties m_cache;
|
||||
};
|
||||
|
||||
template <typename IteratorT>
|
||||
SongIterator makeSongIterator(IteratorT it)
|
||||
{
|
||||
typedef SongPropertiesExtractor<
|
||||
typename IteratorT::value_type::Type
|
||||
> Extractor;
|
||||
static_assert(
|
||||
std::is_convertible<
|
||||
typename std::result_of<Extractor(typename IteratorT::reference)>::type,
|
||||
SongProperties &
|
||||
>::value, "invalid result type of SongPropertiesExtractor");
|
||||
return SongIterator(boost::make_transform_iterator(it, Extractor{}));
|
||||
}
|
||||
|
||||
template <typename ItemT, typename TransformT>
|
||||
ConstSongIterator makeConstSongIterator_(typename NC::Menu<ItemT>::ConstIterator it, TransformT &&map)
|
||||
template <typename ConstIteratorT>
|
||||
ConstSongIterator makeConstSongIterator(ConstIteratorT it)
|
||||
{
|
||||
return ConstSongIterator(boost::make_zip_iterator(boost::make_tuple(
|
||||
typename NC::Menu<ItemT>::ConstPropertiesIterator(it),
|
||||
boost::make_transform_iterator(it, std::forward<TransformT>(map))
|
||||
)));
|
||||
typedef SongPropertiesExtractor<
|
||||
typename ConstIteratorT::value_type::Type
|
||||
> Extractor;
|
||||
static_assert(
|
||||
std::is_convertible<
|
||||
typename std::result_of<Extractor(typename ConstIteratorT::reference)>::type,
|
||||
const SongProperties &
|
||||
>::value, "invalid result type of SongPropertiesExtractor");
|
||||
return ConstSongIterator(boost::make_transform_iterator(it, Extractor{}));
|
||||
}
|
||||
|
||||
#endif // NCMPCPP_HELPERS_SONG_ITERATOR_MAKER_H
|
||||
|
||||
11
src/menu.h
11
src/menu.h
@@ -29,6 +29,7 @@
|
||||
#include <memory>
|
||||
#include <set>
|
||||
|
||||
#include "utility/const.h"
|
||||
#include "strbuffer.h"
|
||||
#include "window.h"
|
||||
|
||||
@@ -197,8 +198,6 @@ struct Menu: Window, List
|
||||
}
|
||||
|
||||
private:
|
||||
enum class Const { Yes, No };
|
||||
|
||||
template <Const const_>
|
||||
struct ExtractProperties
|
||||
{
|
||||
@@ -254,19 +253,19 @@ struct Menu: Window, List
|
||||
typedef std::reverse_iterator<ConstIterator> ConstReverseIterator;
|
||||
|
||||
typedef boost::transform_iterator<
|
||||
typename Item::template ExtractValue<Item::Const::No>,
|
||||
typename Item::template ExtractValue<Const::No>,
|
||||
Iterator> ValueIterator;
|
||||
typedef boost::transform_iterator<
|
||||
typename Item::template ExtractValue<Item::Const::Yes>,
|
||||
typename Item::template ExtractValue<Const::Yes>,
|
||||
ConstIterator> ConstValueIterator;
|
||||
typedef std::reverse_iterator<ValueIterator> ReverseValueIterator;
|
||||
typedef std::reverse_iterator<ConstValueIterator> ConstReverseValueIterator;
|
||||
|
||||
typedef boost::transform_iterator<
|
||||
typename Item::template ExtractProperties<Item::Const::No>,
|
||||
typename Item::template ExtractProperties<Const::No>,
|
||||
Iterator> PropertiesIterator;
|
||||
typedef boost::transform_iterator<
|
||||
typename Item::template ExtractProperties<Item::Const::Yes>,
|
||||
typename Item::template ExtractProperties<Const::Yes>,
|
||||
ConstIterator> ConstPropertiesIterator;
|
||||
|
||||
/// Function helper prototype used to display each option on the screen.
|
||||
|
||||
17
src/mpdpp.h
17
src/mpdpp.h
@@ -260,6 +260,23 @@ struct Item
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
Directory &directory()
|
||||
{
|
||||
return const_cast<Directory &>(
|
||||
static_cast<const Item &>(*this).directory());
|
||||
}
|
||||
Song &song()
|
||||
{
|
||||
return const_cast<Song &>(
|
||||
static_cast<const Item &>(*this).song());
|
||||
}
|
||||
Playlist &playlist()
|
||||
{
|
||||
return const_cast<Playlist &>(
|
||||
static_cast<const Item &>(*this).playlist());
|
||||
}
|
||||
|
||||
const Directory &directory() const
|
||||
{
|
||||
assert(m_type == Type::Directory);
|
||||
|
||||
@@ -73,56 +73,56 @@ namespace pos {
|
||||
}*/
|
||||
|
||||
std::string SEItemToString(const SEItem &ei);
|
||||
bool SEItemEntryMatcher(const Regex::Regex &rx, const NC::Menu<SEItem>::Item &item, bool filter);
|
||||
|
||||
template <bool Const>
|
||||
struct SongExtractor
|
||||
{
|
||||
typedef SongExtractor type;
|
||||
|
||||
typedef typename NC::Menu<SEItem>::Item MenuItem;
|
||||
typedef typename std::conditional<Const, const MenuItem, MenuItem>::type Item;
|
||||
typedef typename std::conditional<Const, const MPD::Song, MPD::Song>::type Song;
|
||||
|
||||
Song *operator()(Item &item) const
|
||||
{
|
||||
Song *ptr = nullptr;
|
||||
if (!item.isSeparator() && item.value().isSong())
|
||||
ptr = &item.value().song();
|
||||
return ptr;
|
||||
}
|
||||
};
|
||||
bool SEItemEntryMatcher(const Regex::Regex &rx,
|
||||
const NC::Menu<SEItem>::Item &item,
|
||||
bool filter);
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
struct SongPropertiesExtractor<SEItem>
|
||||
{
|
||||
template <typename ItemT>
|
||||
auto &operator()(ItemT &item) const
|
||||
{
|
||||
auto s = !item.isSeparator() && item.value().isSong()
|
||||
? &item.value().song()
|
||||
: nullptr;
|
||||
return m_cache.assign(&item.properties(), s);
|
||||
}
|
||||
|
||||
private:
|
||||
mutable SongProperties m_cache;
|
||||
};
|
||||
|
||||
SongIterator SearchEngineWindow::currentS()
|
||||
{
|
||||
return makeSongIterator_<SEItem>(current(), SongExtractor<false>());
|
||||
return makeSongIterator(current());
|
||||
}
|
||||
|
||||
ConstSongIterator SearchEngineWindow::currentS() const
|
||||
{
|
||||
return makeConstSongIterator_<SEItem>(current(), SongExtractor<true>());
|
||||
return makeConstSongIterator(current());
|
||||
}
|
||||
|
||||
SongIterator SearchEngineWindow::beginS()
|
||||
{
|
||||
return makeSongIterator_<SEItem>(begin(), SongExtractor<false>());
|
||||
return makeSongIterator(begin());
|
||||
}
|
||||
|
||||
ConstSongIterator SearchEngineWindow::beginS() const
|
||||
{
|
||||
return makeConstSongIterator_<SEItem>(begin(), SongExtractor<true>());
|
||||
return makeConstSongIterator(begin());
|
||||
}
|
||||
|
||||
SongIterator SearchEngineWindow::endS()
|
||||
{
|
||||
return makeSongIterator_<SEItem>(end(), SongExtractor<false>());
|
||||
return makeSongIterator(end());
|
||||
}
|
||||
|
||||
ConstSongIterator SearchEngineWindow::endS() const
|
||||
{
|
||||
return makeConstSongIterator_<SEItem>(end(), SongExtractor<true>());
|
||||
return makeConstSongIterator(end());
|
||||
}
|
||||
|
||||
std::vector<MPD::Song> SearchEngineWindow::getSelectedSongs()
|
||||
|
||||
@@ -22,53 +22,34 @@
|
||||
#include "song_info.h"
|
||||
#include "utility/functional.h"
|
||||
|
||||
namespace {
|
||||
|
||||
template <bool Const>
|
||||
struct SongExtractor
|
||||
{
|
||||
typedef SongExtractor type;
|
||||
|
||||
typedef typename NC::Menu<MPD::Song>::Item MenuItem;
|
||||
typedef typename std::conditional<Const, const MenuItem, MenuItem>::type Item;
|
||||
typedef typename std::conditional<Const, const MPD::Song, MPD::Song>::type Song;
|
||||
|
||||
Song *operator()(Item &item) const
|
||||
{
|
||||
return &item.value();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
SongIterator SongMenu::currentS()
|
||||
{
|
||||
return makeSongIterator_<MPD::Song>(current(), SongExtractor<false>());
|
||||
return makeSongIterator(current());
|
||||
}
|
||||
|
||||
ConstSongIterator SongMenu::currentS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::Song>(current(), SongExtractor<true>());
|
||||
return makeConstSongIterator(current());
|
||||
}
|
||||
|
||||
SongIterator SongMenu::beginS()
|
||||
{
|
||||
return makeSongIterator_<MPD::Song>(begin(), SongExtractor<false>());
|
||||
return makeSongIterator(begin());
|
||||
}
|
||||
|
||||
ConstSongIterator SongMenu::beginS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::Song>(begin(), SongExtractor<true>());
|
||||
return makeConstSongIterator(begin());
|
||||
}
|
||||
|
||||
SongIterator SongMenu::endS()
|
||||
{
|
||||
return makeSongIterator_<MPD::Song>(end(), SongExtractor<false>());
|
||||
return makeSongIterator(end());
|
||||
}
|
||||
|
||||
ConstSongIterator SongMenu::endS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::Song>(end(), SongExtractor<true>());
|
||||
return makeConstSongIterator(end());
|
||||
}
|
||||
|
||||
std::vector<MPD::Song> SongMenu::getSelectedSongs()
|
||||
|
||||
@@ -22,25 +22,85 @@
|
||||
#define NCMPCPP_SONG_LIST_H
|
||||
|
||||
#include <boost/range/detail/any_iterator.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
#include "menu.h"
|
||||
#include "song.h"
|
||||
#include "utility/const.h"
|
||||
|
||||
template <typename ValueT>
|
||||
struct SongProperties
|
||||
{
|
||||
enum class State { Undefined, Const, Mutable };
|
||||
|
||||
SongProperties()
|
||||
: m_state(State::Undefined)
|
||||
{ }
|
||||
|
||||
SongProperties &assign(NC::List::Properties *properties_, MPD::Song *song_)
|
||||
{
|
||||
m_state = State::Mutable;
|
||||
m_properties = properties_;
|
||||
m_song = song_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
SongProperties &assign(const NC::List::Properties *properties_, const MPD::Song *song_)
|
||||
{
|
||||
m_state = State::Const;
|
||||
m_const_properties = properties_;
|
||||
m_const_song = song_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const NC::List::Properties &properties() const
|
||||
{
|
||||
assert(m_state != State::Undefined);
|
||||
return *m_const_properties;
|
||||
}
|
||||
const MPD::Song *song() const
|
||||
{
|
||||
assert(m_state != State::Undefined);
|
||||
return m_const_song;
|
||||
}
|
||||
|
||||
NC::List::Properties &properties()
|
||||
{
|
||||
assert(m_state == State::Mutable);
|
||||
return *m_properties;
|
||||
}
|
||||
MPD::Song *song()
|
||||
{
|
||||
assert(m_state == State::Mutable);
|
||||
return m_song;
|
||||
}
|
||||
|
||||
private:
|
||||
State m_state;
|
||||
|
||||
union {
|
||||
NC::List::Properties *m_properties;
|
||||
const NC::List::Properties *m_const_properties;
|
||||
};
|
||||
union {
|
||||
MPD::Song *m_song;
|
||||
const MPD::Song *m_const_song;
|
||||
};
|
||||
};
|
||||
|
||||
template <Const const_>
|
||||
using SongIteratorT = boost::range_detail::any_iterator<
|
||||
ValueT,
|
||||
typename std::conditional<
|
||||
const_ == Const::Yes,
|
||||
const SongProperties,
|
||||
SongProperties>::type,
|
||||
boost::random_access_traversal_tag,
|
||||
const ValueT, // const needed, see https://svn.boost.org/trac/boost/ticket/10493
|
||||
typename std::conditional<
|
||||
const_ == Const::Yes,
|
||||
const SongProperties &,
|
||||
SongProperties &>::type,
|
||||
std::ptrdiff_t
|
||||
>;
|
||||
>;
|
||||
|
||||
typedef SongIteratorT<boost::tuple<NC::List::Properties &, MPD::Song *>> SongIterator;
|
||||
typedef SongIteratorT<boost::tuple<const NC::List::Properties &, const MPD::Song *>> ConstSongIterator;
|
||||
|
||||
namespace Bit {
|
||||
const size_t Properties = 0;
|
||||
const size_t Song = 1;
|
||||
}
|
||||
typedef SongIteratorT<Const::No> SongIterator;
|
||||
typedef SongIteratorT<Const::Yes> ConstSongIterator;
|
||||
|
||||
struct SongList
|
||||
{
|
||||
|
||||
@@ -87,51 +87,36 @@ std::string SongToString(const MPD::MutableSong &s);
|
||||
bool DirEntryMatcher(const Regex::Regex &rx, const std::pair<std::string, std::string> &dir, bool filter);
|
||||
bool SongEntryMatcher(const Regex::Regex &rx, const MPD::MutableSong &s);
|
||||
|
||||
template <bool Const>
|
||||
struct SongExtractor
|
||||
{
|
||||
typedef SongExtractor type;
|
||||
|
||||
typedef typename NC::Menu<MPD::MutableSong>::Item MenuItem;
|
||||
typedef typename std::conditional<Const, const MenuItem, MenuItem>::type Item;
|
||||
typedef typename std::conditional<Const, const MPD::Song, MPD::Song>::type Song;
|
||||
|
||||
Song *operator()(Item &item) const
|
||||
{
|
||||
return &item.value();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
SongIterator TagsWindow::currentS()
|
||||
{
|
||||
return makeSongIterator_<MPD::MutableSong>(current(), SongExtractor<false>());
|
||||
return makeSongIterator(current());
|
||||
}
|
||||
|
||||
ConstSongIterator TagsWindow::currentS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::MutableSong>(current(), SongExtractor<true>());
|
||||
return makeConstSongIterator(current());
|
||||
}
|
||||
|
||||
SongIterator TagsWindow::beginS()
|
||||
{
|
||||
return makeSongIterator_<MPD::MutableSong>(begin(), SongExtractor<false>());
|
||||
return makeSongIterator(begin());
|
||||
}
|
||||
|
||||
ConstSongIterator TagsWindow::beginS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::MutableSong>(begin(), SongExtractor<true>());
|
||||
return makeConstSongIterator(begin());
|
||||
}
|
||||
|
||||
SongIterator TagsWindow::endS()
|
||||
{
|
||||
return makeSongIterator_<MPD::MutableSong>(end(), SongExtractor<false>());
|
||||
return makeSongIterator(end());
|
||||
}
|
||||
|
||||
ConstSongIterator TagsWindow::endS() const
|
||||
{
|
||||
return makeConstSongIterator_<MPD::MutableSong>(end(), SongExtractor<true>());
|
||||
return makeConstSongIterator(end());
|
||||
}
|
||||
|
||||
std::vector<MPD::Song> TagsWindow::getSelectedSongs()
|
||||
|
||||
26
src/utility/const.h
Normal file
26
src/utility/const.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/***************************************************************************
|
||||
* Copyright (C) 2008-2016 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_UTILITY_CONST_H
|
||||
#define NCMPCPP_UTILITY_CONST_H
|
||||
|
||||
enum class Const { Yes, No };
|
||||
|
||||
#endif // NCMPCPP_UTILITY_CONST_H
|
||||
Reference in New Issue
Block a user