diff options
author | Max Kellermann <max@duempel.org> | 2014-06-10 21:15:40 +0200 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2014-06-16 18:39:16 +0200 |
commit | 3ca0a39a357d9be9c85de4892ac02716f8af2ae8 (patch) | |
tree | 88c87573974f6609a1dc68cf20e5901600613280 /src/db/plugins/simple/Directory.hxx | |
parent | 52594e64d0f48eb83c9bf54eb1ac95a6de881829 (diff) | |
download | mpd-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 '')
-rw-r--r-- | src/db/plugins/simple/Directory.hxx | 60 |
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. * |