diff foosdk/sdk/foobar2000/helpers/metadb_handle_set.h @ 1:20d02a178406 default tip

*: check in everything else yay
author Paper <paper@tflc.us>
date Mon, 05 Jan 2026 02:15:46 -0500
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/foosdk/sdk/foobar2000/helpers/metadb_handle_set.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,81 @@
+#pragma once
+#include <set>
+class metadb_handle;
+
+// Roughly same as pfc::avltree_t<metadb_handle_ptr> or std::set<metadb_handle_ptr>, but optimized for use with large amounts of items
+class metadb_handle_set {
+public:
+	metadb_handle_set() {}
+	template<typename ptr_t>
+	bool add_item_check(ptr_t const & item) { return add_item_check_(&*item); }
+	template<typename ptr_t>
+	bool remove_item(ptr_t const & item) { return remove_item_(&*item); }
+
+	bool add_item_check_(metadb_handle * p) {
+		bool rv = m_content.insert(p).second;
+		if (rv) p->service_add_ref();
+		return rv;
+	}
+	bool remove_item_(metadb_handle * p) {
+		bool rv = m_content.erase(p) != 0;
+		if (rv) p->service_release();
+		return rv;
+	}
+	size_t size() const {return m_content.size();}
+	size_t get_count() const {return m_content.size(); }
+	template<typename ptr_t>
+	bool contains(ptr_t const & item) const {
+		return m_content.count(&*item) != 0;
+	}
+	template<typename ptr_t>
+	bool have_item(ptr_t const & item) const {
+		return m_content.count(&*item) != 0;
+	}
+	void operator+=(metadb_handle::ptr const & item) {
+		add_item_check_(item.get_ptr());
+	}
+	void operator-=(metadb_handle::ptr const & item) {
+		remove_item_(item.get_ptr());
+	}
+	void operator+=(metadb_handle::ptr && item) {
+		auto p = item.detach();
+		bool added = m_content.insert(p).second;
+		if (!added) p->service_release();
+	}
+	void clear() {
+		for (auto p : m_content) p->service_release();
+		m_content.clear();
+	}
+	void remove_all() {	clear();}
+	template<typename callback_t>
+	void enumerate(callback_t & cb) const {
+		for (auto iter : m_content) cb(iter);
+	}
+	typedef std::set<metadb_handle*> impl_t;
+	typedef impl_t::const_iterator const_iterator;
+	const_iterator begin() const { return m_content.begin(); }
+	const_iterator end() const { return m_content.end(); }
+
+	metadb_handle_list to_list() const {
+		metadb_handle_list ret; ret.prealloc(m_content.size());
+		for (auto h : m_content) {
+			ret.add_item(h);
+		}
+		return ret;
+	}
+	metadb_handle_set(const metadb_handle_set& src) { _copy(src); }
+	void operator=(const metadb_handle_set& src) { _copy(src); }
+
+	metadb_handle_set(metadb_handle_set&& src) noexcept { _move(src); }
+	void operator=(metadb_handle_set&& src) noexcept { _move(src); }
+private:
+	void _copy(const metadb_handle_set& src) {
+		m_content = src.m_content;
+		for (auto h : m_content) h->service_add_ref();
+	}
+	void _move(metadb_handle_set& src) {
+		m_content = std::move(src.m_content); src.m_content.clear();
+	}
+
+	impl_t m_content;
+};