summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-01-02 22:16:52 +0100
committerMax Kellermann <max@duempel.org>2013-01-03 02:25:06 +0100
commit9023ba4a81d597c8694432655833cf23d83c6cde (patch)
tree304c2465ea160297dff17302f36c4cc38687ccb6
parent83488848e1091024a0a307b1539c1a85762ee1f1 (diff)
PlaylistVector: use std::list
-rw-r--r--Makefile.am2
-rw-r--r--src/Directory.cxx9
-rw-r--r--src/Directory.hxx11
-rw-r--r--src/DirectorySave.cxx4
-rw-r--r--src/PlaylistDatabase.cxx11
-rw-r--r--src/PlaylistDatabase.hxx6
-rw-r--r--src/PlaylistInfo.hxx13
-rw-r--r--src/PlaylistVector.cxx55
-rw-r--r--src/PlaylistVector.hxx68
-rw-r--r--src/UpdateDatabase.cxx2
-rw-r--r--src/UpdateWalk.cxx16
11 files changed, 84 insertions, 113 deletions
diff --git a/Makefile.am b/Makefile.am
index e7a9ffb24..2e9efd15c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1358,7 +1358,7 @@ test_test_pcm_LDADD = \
test_TestQueuePriority_SOURCES = \
src/queue.c \
- test/TestQueuePriority.c
+ test/TestQueuePriority.cxx
test_TestQueuePriority_LDADD = \
$(GLIB_LIBS)
diff --git a/src/Directory.cxx b/src/Directory.cxx
index dec772c01..f27b3d474 100644
--- a/src/Directory.cxx
+++ b/src/Directory.cxx
@@ -55,7 +55,6 @@ Directory::Directory()
{
INIT_LIST_HEAD(&children);
INIT_LIST_HEAD(&songs);
- INIT_LIST_HEAD(&playlists);
path[0] = 0;
}
@@ -64,15 +63,12 @@ Directory::Directory(const char *_path)
{
INIT_LIST_HEAD(&children);
INIT_LIST_HEAD(&songs);
- INIT_LIST_HEAD(&playlists);
strcpy(path, _path);
}
Directory::~Directory()
{
- playlist_vector_deinit(&playlists);
-
struct song *song, *ns;
directory_for_each_song_safe(song, ns, this)
song_free(song);
@@ -318,9 +314,8 @@ Directory::Walk(bool recursive, const SongFilter *filter,
}
if (visit_playlist) {
- PlaylistInfo *i;
- directory_for_each_playlist(i, this)
- if (!visit_playlist(*i, *this, error_r))
+ for (const PlaylistInfo &p : playlists)
+ if (!visit_playlist(p, *this, error_r))
return false;
}
diff --git a/src/Directory.hxx b/src/Directory.hxx
index ab23a6922..710f47921 100644
--- a/src/Directory.hxx
+++ b/src/Directory.hxx
@@ -24,6 +24,7 @@
#include "util/list.h"
#include "gcc.h"
#include "DatabaseVisitor.hxx"
+#include "PlaylistVector.hxx"
#include <glib.h>
#include <stdbool.h>
@@ -44,12 +45,6 @@
#define directory_for_each_song_safe(pos, n, directory) \
list_for_each_entry_safe(pos, n, &directory->songs, siblings)
-#define directory_for_each_playlist(pos, directory) \
- list_for_each_entry(pos, &directory->playlists, siblings)
-
-#define directory_for_each_playlist_safe(pos, n, directory) \
- list_for_each_entry_safe(pos, n, &directory->playlists, siblings)
-
struct song;
struct db_visitor;
class SongFilter;
@@ -81,7 +76,7 @@ struct Directory {
*/
struct list_head songs;
- struct list_head playlists;
+ PlaylistVector playlists;
Directory *parent;
time_t mtime;
@@ -179,7 +174,7 @@ public:
bool IsEmpty() const {
return list_empty(&children) &&
list_empty(&songs) &&
- list_empty(&playlists);
+ playlists.empty();
}
gcc_pure
diff --git a/src/DirectorySave.cxx b/src/DirectorySave.cxx
index 6fcc9ccc0..cd750c9b2 100644
--- a/src/DirectorySave.cxx
+++ b/src/DirectorySave.cxx
@@ -72,7 +72,7 @@ directory_save(FILE *fp, const Directory *directory)
directory_for_each_song(song, directory)
song_save(fp, song);
- playlist_vector_save(fp, &directory->playlists);
+ playlist_vector_save(fp, directory->playlists);
if (!directory->IsRoot())
fprintf(fp, DIRECTORY_END "%s\n", directory->GetPath());
@@ -168,7 +168,7 @@ directory_load(FILE *fp, Directory *directory,
buffer */
char *name = g_strdup(line + sizeof(PLAYLIST_META_BEGIN) - 1);
- if (!playlist_metadata_load(fp, &directory->playlists,
+ if (!playlist_metadata_load(fp, directory->playlists,
name, buffer, error)) {
g_free(name);
return false;
diff --git a/src/PlaylistDatabase.cxx b/src/PlaylistDatabase.cxx
index bbfdf7481..4604a8956 100644
--- a/src/PlaylistDatabase.cxx
+++ b/src/PlaylistDatabase.cxx
@@ -36,18 +36,17 @@ playlist_database_quark(void)
}
void
-playlist_vector_save(FILE *fp, const struct list_head *pv)
+playlist_vector_save(FILE *fp, const PlaylistVector &pv)
{
- PlaylistInfo *pm;
- playlist_vector_for_each(pm, pv)
+ for (const PlaylistInfo &pi : pv)
fprintf(fp, PLAYLIST_META_BEGIN "%s\n"
"mtime: %li\n"
"playlist_end\n",
- pm->name.c_str(), (long)pm->mtime);
+ pi.name.c_str(), (long)pi.mtime);
}
bool
-playlist_metadata_load(FILE *fp, struct list_head *pv, const char *name,
+playlist_metadata_load(FILE *fp, PlaylistVector &pv, const char *name,
GString *buffer, GError **error_r)
{
PlaylistInfo pm(name, 0);
@@ -76,6 +75,6 @@ playlist_metadata_load(FILE *fp, struct list_head *pv, const char *name,
}
}
- playlist_vector_update_or_add(pv, std::move(pm));
+ pv.UpdateOrInsert(std::move(pm));
return true;
}
diff --git a/src/PlaylistDatabase.hxx b/src/PlaylistDatabase.hxx
index 0b4cd3f3a..da2bb6b97 100644
--- a/src/PlaylistDatabase.hxx
+++ b/src/PlaylistDatabase.hxx
@@ -27,13 +27,13 @@
#define PLAYLIST_META_BEGIN "playlist_begin: "
-struct list_head;
+class PlaylistVector;
void
-playlist_vector_save(FILE *fp, const struct list_head *pv);
+playlist_vector_save(FILE *fp, const PlaylistVector &pv);
bool
-playlist_metadata_load(FILE *fp, struct list_head *pv, const char *name,
+playlist_metadata_load(FILE *fp, PlaylistVector &pv, const char *name,
GString *buffer, GError **error_r);
#endif
diff --git a/src/PlaylistInfo.hxx b/src/PlaylistInfo.hxx
index fffafd819..e4cf0f4ef 100644
--- a/src/PlaylistInfo.hxx
+++ b/src/PlaylistInfo.hxx
@@ -22,6 +22,7 @@
#include "check.h"
#include "util/list.h"
+#include "gcc.h"
#include <string>
@@ -40,6 +41,18 @@ struct PlaylistInfo {
time_t mtime;
+ class CompareName {
+ const char *const name;
+
+ public:
+ constexpr CompareName(const char *_name):name(_name) {}
+
+ gcc_pure
+ bool operator()(const PlaylistInfo &pi) const {
+ return pi.name.compare(name) == 0;
+ }
+ };
+
template<typename N>
PlaylistInfo(N &&_name, time_t _mtime)
:name(std::forward<N>(_name)), mtime(_mtime) {}
diff --git a/src/PlaylistVector.cxx b/src/PlaylistVector.cxx
index f1f13567f..06c7b9ff0 100644
--- a/src/PlaylistVector.cxx
+++ b/src/PlaylistVector.cxx
@@ -21,71 +21,48 @@
#include "PlaylistVector.hxx"
#include "DatabaseLock.hxx"
+#include <algorithm>
+
#include <assert.h>
#include <string.h>
#include <glib.h>
-void
-playlist_vector_deinit(struct list_head *pv)
-{
- assert(pv != NULL);
-
- PlaylistInfo *pm, *n;
- playlist_vector_for_each_safe(pm, n, pv)
- delete pm;
-}
-
-PlaylistInfo *
-playlist_vector_find(struct list_head *pv, const char *name)
+PlaylistVector::iterator
+PlaylistVector::find(const char *name)
{
assert(holding_db_lock());
- assert(pv != NULL);
assert(name != NULL);
- PlaylistInfo *pm;
- playlist_vector_for_each(pm, pv)
- if (pm->name.compare(name) == 0)
- return pm;
-
- return NULL;
-}
-
-void
-playlist_vector_add(struct list_head *pv, PlaylistInfo &&pi)
-{
- assert(holding_db_lock());
-
- PlaylistInfo *pm = new PlaylistInfo(std::move(pi));
- list_add_tail(&pm->siblings, pv);
+ return std::find_if(begin(), end(),
+ PlaylistInfo::CompareName(name));
}
bool
-playlist_vector_update_or_add(struct list_head *pv, PlaylistInfo &&pi)
+PlaylistVector::UpdateOrInsert(PlaylistInfo &&pi)
{
assert(holding_db_lock());
- PlaylistInfo *pm = playlist_vector_find(pv, pi.name.c_str());
- if (pm != NULL) {
- if (pi.mtime == pm->mtime)
+ auto i = find(pi.name.c_str());
+ if (i != end()) {
+ if (pi.mtime == i->mtime)
return false;
- pm->mtime = pi.mtime;
+ i->mtime = pi.mtime;
} else
- playlist_vector_add(pv, std::move(pi));
+ push_back(std::move(pi));
return true;
}
bool
-playlist_vector_remove(struct list_head *pv, const char *name)
+PlaylistVector::erase(const char *name)
{
assert(holding_db_lock());
- PlaylistInfo *pm = playlist_vector_find(pv, name);
- if (pm == NULL)
+ auto i = find(name);
+ if (i == end())
return false;
- list_del(&pm->siblings);
- delete pm;
+ erase(i);
return true;
}
diff --git a/src/PlaylistVector.hxx b/src/PlaylistVector.hxx
index 14445315c..0a4cd95b3 100644
--- a/src/PlaylistVector.hxx
+++ b/src/PlaylistVector.hxx
@@ -21,43 +21,35 @@
#define MPD_PLAYLIST_VECTOR_HXX
#include "PlaylistInfo.hxx"
-#include "util/list.h"
-
-#include <sys/time.h>
-
-#define playlist_vector_for_each(pos, head) \
- list_for_each_entry(pos, head, siblings)
-
-#define playlist_vector_for_each_safe(pos, n, head) \
- list_for_each_entry_safe(pos, n, head, siblings)
-
-void
-playlist_vector_deinit(struct list_head *pv);
-
-/**
- * Caller must lock the #db_mutex.
- */
-PlaylistInfo *
-playlist_vector_find(struct list_head *pv, const char *name);
-
-/**
- * Caller must lock the #db_mutex.
- */
-void
-playlist_vector_add(struct list_head *pv, PlaylistInfo &&pi);
-
-/**
- * Caller must lock the #db_mutex.
- *
- * @return true if the vector or one of its items was modified
- */
-bool
-playlist_vector_update_or_add(struct list_head *pv, PlaylistInfo &&pi);
-
-/**
- * Caller must lock the #db_mutex.
- */
-bool
-playlist_vector_remove(struct list_head *pv, const char *name);
+#include "gcc.h"
+
+#include <list>
+
+class PlaylistVector : protected std::list<PlaylistInfo> {
+protected:
+ /**
+ * Caller must lock the #db_mutex.
+ */
+ gcc_pure
+ iterator find(const char *name);
+
+public:
+ using std::list<PlaylistInfo>::empty;
+ using std::list<PlaylistInfo>::begin;
+ using std::list<PlaylistInfo>::end;
+ using std::list<PlaylistInfo>::erase;
+
+ /**
+ * Caller must lock the #db_mutex.
+ *
+ * @return true if the vector or one of its items was modified
+ */
+ bool UpdateOrInsert(PlaylistInfo &&pi);
+
+ /**
+ * Caller must lock the #db_mutex.
+ */
+ bool erase(const char *name);
+};
#endif /* SONGVEC_H */
diff --git a/src/UpdateDatabase.cxx b/src/UpdateDatabase.cxx
index 50697511c..984fb1be8 100644
--- a/src/UpdateDatabase.cxx
+++ b/src/UpdateDatabase.cxx
@@ -96,7 +96,7 @@ delete_name_in(Directory *parent, const char *name)
modified = true;
}
- playlist_vector_remove(&parent->playlists, name);
+ parent->playlists.erase(name);
db_unlock();
diff --git a/src/UpdateWalk.cxx b/src/UpdateWalk.cxx
index 4923f083a..eb0565832 100644
--- a/src/UpdateWalk.cxx
+++ b/src/UpdateWalk.cxx
@@ -158,14 +158,15 @@ purge_deleted_from_directory(Directory *directory)
g_free(path);
}
- PlaylistInfo *pm, *np;
- directory_for_each_playlist_safe(pm, np, directory) {
- if (!directory_child_is_regular(directory, pm->name.c_str())) {
+ for (auto i = directory->playlists.begin(),
+ end = directory->playlists.end();
+ i != end;) {
+ if (!directory_child_is_regular(directory, i->name.c_str())) {
db_lock();
- playlist_vector_remove(&directory->playlists,
- pm->name.c_str());
+ i = directory->playlists.erase(i);
db_unlock();
- }
+ } else
+ ++i;
}
}
@@ -217,8 +218,7 @@ update_playlist_file2(Directory *directory,
PlaylistInfo pi(name, st->st_mtime);
db_lock();
- if (playlist_vector_update_or_add(&directory->playlists,
- std::move(pi)))
+ if (directory->playlists.UpdateOrInsert(std::move(pi)))
modified = true;
db_unlock();
return true;