aboutsummaryrefslogtreecommitdiffstats
path: root/src/db/plugins/simple/Directory.hxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2014-06-10 21:15:40 +0200
committerMax Kellermann <max@duempel.org>2014-06-16 18:39:16 +0200
commit3ca0a39a357d9be9c85de4892ac02716f8af2ae8 (patch)
tree88c87573974f6609a1dc68cf20e5901600613280 /src/db/plugins/simple/Directory.hxx
parent52594e64d0f48eb83c9bf54eb1ac95a6de881829 (diff)
downloadmpd-3ca0a39a357d9be9c85de4892ac02716f8af2ae8.tar.gz
mpd-3ca0a39a357d9be9c85de4892ac02716f8af2ae8.tar.xz
mpd-3ca0a39a357d9be9c85de4892ac02716f8af2ae8.zip
db/simple: use class boost::intrusive::list
Remove the C list_head library and use type-safe C++ instead.
Diffstat (limited to 'src/db/plugins/simple/Directory.hxx')
-rw-r--r--src/db/plugins/simple/Directory.hxx60
1 files changed, 41 insertions, 19 deletions
diff --git a/src/db/plugins/simple/Directory.hxx b/src/db/plugins/simple/Directory.hxx
index 029815d95..80675bd21 100644
--- a/src/db/plugins/simple/Directory.hxx
+++ b/src/db/plugins/simple/Directory.hxx
@@ -21,10 +21,12 @@
#define MPD_DIRECTORY_HXX
#include "check.h"
-#include "util/list.h"
#include "Compiler.h"
#include "db/Visitor.hxx"
#include "db/PlaylistVector.hxx"
+#include "Song.hxx"
+
+#include <boost/intrusive/list.hpp>
#include <string>
@@ -41,25 +43,22 @@ static constexpr unsigned DEVICE_INARCHIVE = -1;
*/
static constexpr unsigned DEVICE_CONTAINER = -2;
-#define directory_for_each_child(pos, directory) \
- list_for_each_entry(pos, &(directory).children, siblings)
-
-#define directory_for_each_child_safe(pos, n, directory) \
- list_for_each_entry_safe(pos, n, &(directory).children, siblings)
-
-#define directory_for_each_song(pos, directory) \
- list_for_each_entry(pos, &(directory).songs, siblings)
-
-#define directory_for_each_song_safe(pos, n, directory) \
- list_for_each_entry_safe(pos, n, &(directory).songs, siblings)
-
-struct Song;
struct db_visitor;
class SongFilter;
class Error;
class Database;
struct Directory {
+ static constexpr auto link_mode = boost::intrusive::normal_link;
+ typedef boost::intrusive::link_mode<link_mode> LinkMode;
+ typedef boost::intrusive::list_member_hook<LinkMode> Hook;
+
+ struct Disposer {
+ void operator()(Directory *directory) const {
+ delete directory;
+ }
+ };
+
/**
* Pointers to the siblings of this directory within the
* parent directory. It is unused (undefined) in the root
@@ -68,7 +67,12 @@ struct Directory {
* This attribute is protected with the global #db_mutex.
* Read access in the update thread does not need protection.
*/
- struct list_head siblings;
+ Hook siblings;
+
+ typedef boost::intrusive::member_hook<Directory, Hook,
+ &Directory::siblings> SiblingsHook;
+ typedef boost::intrusive::list<Directory, SiblingsHook,
+ boost::intrusive::constant_time_size<false>> List;
/**
* A doubly linked list of child directories.
@@ -76,7 +80,7 @@ struct Directory {
* This attribute is protected with the global #db_mutex.
* Read access in the update thread does not need protection.
*/
- struct list_head children;
+ List children;
/**
* A doubly linked list of songs within this directory.
@@ -84,7 +88,7 @@ struct Directory {
* This attribute is protected with the global #db_mutex.
* Read access in the update thread does not need protection.
*/
- struct list_head songs;
+ SongList songs;
PlaylistVector playlists;
@@ -186,8 +190,8 @@ public:
gcc_pure
bool IsEmpty() const {
- return list_empty(&children) &&
- list_empty(&songs) &&
+ return children.empty() &&
+ songs.empty() &&
playlists.empty();
}
@@ -210,6 +214,24 @@ public:
return parent == nullptr;
}
+ template<typename T>
+ void ForEachChildSafe(T &&t) {
+ const auto end = children.end();
+ for (auto i = children.begin(), next = i; i != end; i = next) {
+ next = std::next(i);
+ t(*i);
+ }
+ }
+
+ template<typename T>
+ void ForEachSongSafe(T &&t) {
+ const auto end = songs.end();
+ for (auto i = songs.begin(), next = i; i != end; i = next) {
+ next = std::next(i);
+ t(*i);
+ }
+ }
+
/**
* Look up a song in this directory by its name.
*