Queue: use std::vector instead of GPtrArray
authorMax Kellermann <max@musicpd.org>
Tue, 20 Feb 2018 07:15:52 +0000 (08:15 +0100)
committerMax Kellermann <max@musicpd.org>
Tue, 20 Feb 2018 15:56:42 +0000 (16:56 +0100)
src/Queue.cxx
src/Queue.hxx
src/screen_client.cxx

index b355cd9..bf263f6 100644 (file)
 
 #include "Queue.hxx"
 
+#include <algorithm>
+
 #include <string.h>
 
 void
 MpdQueue::clear()
 {
        version = 0;
-
-       for (unsigned i = 0; i < list->len; ++i) {
-               auto *song = &(*this)[i];
-               mpd_song_free(song);
-       }
-
-       g_ptr_array_set_size(list, 0);
-}
-
-MpdQueue::~MpdQueue()
-{
-       if (list != nullptr) {
-               clear();
-               g_ptr_array_free(list, true);
-       }
 }
 
 const struct mpd_song *
 MpdQueue::GetChecked(int idx) const
 {
-       if (idx < 0 || (guint)idx >= size())
+       if (idx < 0 || (size_type)idx >= size())
                return nullptr;
 
        return &(*this)[idx];
@@ -58,28 +45,28 @@ MpdQueue::Move(unsigned dest, unsigned src)
        assert(dest < size());
        assert(src != dest);
 
-       auto &song = (*this)[src];
+       auto song = std::move(items[src]);
 
        if (src < dest) {
-               memmove(&list->pdata[src],
-                       &list->pdata[src + 1],
-                       sizeof(list->pdata[0]) * (dest - src));
-               list->pdata[dest] = &song;
+               std::move(std::next(items.begin(), src + 1),
+                         std::next(items.begin(), dest + 1),
+                         std::next(items.begin(), src));
        } else {
-               memmove(&list->pdata[dest + 1],
-                       &list->pdata[dest],
-                       sizeof(list->pdata[0]) * (src - dest));
-               list->pdata[dest] = &song;
+               std::move(std::next(items.begin(), dest),
+                                  std::next(items.begin(), src),
+                                  std::next(items.begin(), dest + 1));
        }
+
+       assert(!items[dest]);
+       items[dest] = std::move(song);
 }
 
 int
 MpdQueue::Find(const struct mpd_song &song) const
 {
-       for (guint i = 0; i < size(); ++i) {
+       for (size_type i = 0; i < size(); ++i)
                if (&(*this)[i] == &song)
-                       return (gint)i;
-       }
+                       return i;
 
        return -1;
 }
@@ -87,10 +74,10 @@ MpdQueue::Find(const struct mpd_song &song) const
 int
 MpdQueue::FindId(unsigned id) const
 {
-       for (guint i = 0; i < size(); ++i) {
+       for (size_type i = 0; i < size(); ++i) {
                const auto &song = (*this)[i];
                if (mpd_song_get_id(&song) == id)
-                       return (gint)i;
+                       return i;
        }
 
        return -1;
@@ -99,10 +86,10 @@ MpdQueue::FindId(unsigned id) const
 int
 MpdQueue::FindUri(const char *filename) const
 {
-       for (guint i = 0; i < size(); ++i) {
+       for (size_type i = 0; i < size(); ++i) {
                const auto &song = (*this)[i];
                if (strcmp(mpd_song_get_uri(&song), filename) == 0)
-                       return (gint)i;
+                       return i;
        }
 
        return -1;
index 5eb7179..1a0582f 100644 (file)
 
 #include <mpd/client.h>
 
+#include <vector>
+#include <memory>
+
 #include <assert.h>
-#include <glib.h>
+
+struct SongDeleter {
+       void operator()(struct mpd_song *song) const {
+               mpd_song_free(song);
+       }
+};
 
 struct MpdQueue {
        /* queue version number (obtained from mpd_status) */
        unsigned version = 0;
 
+       using Vector = std::vector<std::unique_ptr<struct mpd_song, SongDeleter>>;
+
        /* the list */
-       GPtrArray *list = g_ptr_array_sized_new(1024);;
+       Vector items;
 
-       ~MpdQueue();
+       using size_type = Vector::size_type;
 
-       guint size() const {
-               return list->len;
+       size_type size() const {
+               return items.size();
        }
 
        bool empty() const {
-               return size() == 0;
+               return items.empty();
        }
 
        /** remove and free all songs in the playlist */
        void clear();
 
-       const struct mpd_song &operator[](guint i) const {
+       const struct mpd_song &operator[](size_type i) const {
                assert(i < size());
 
-               return *(const struct mpd_song *)g_ptr_array_index(list, i);
+               return *items[i];
        }
 
-       struct mpd_song &operator[](guint i) {
+       struct mpd_song &operator[](size_type i) {
                assert(i < size());
 
-               return *(struct mpd_song *)g_ptr_array_index(list, i);
+               return *items[i];
        }
 
        gcc_pure
        const struct mpd_song *GetChecked(int i) const;
 
        void push_back(const struct mpd_song &song) {
-               g_ptr_array_add(list, mpd_song_dup(&song));
-       }
-
-       void Set(guint i, const struct mpd_song &song) {
-               assert(i < size());
-
-               g_ptr_array_index(list, i) = mpd_song_dup(&song);
+               items.emplace_back(mpd_song_dup(&song));
        }
 
-       void Replace(guint i, const struct mpd_song &song) {
-               mpd_song_free(&(*this)[i]);
-               Set(i, song);
+       void Replace(size_type i, const struct mpd_song &song) {
+               items[i].reset(mpd_song_dup(&song));
        }
 
-       void RemoveIndex(guint i) {
-               mpd_song_free((struct mpd_song *)g_ptr_array_remove_index(list, i));
+       void RemoveIndex(size_type i) {
+               items.erase(std::next(items.begin(), i));
        }
 
        void Move(unsigned dest, unsigned src);
index 3be28e8..17028c2 100644 (file)
@@ -23,6 +23,8 @@
 #include "i18n.h"
 #include "charset.hxx"
 
+#include <glib.h>
+
 void
 screen_database_update(struct mpdclient *c, const char *path)
 {