diff foosdk/sdk/pfc/iterators.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/pfc/iterators.h	Mon Jan 05 02:15:46 2026 -0500
@@ -0,0 +1,199 @@
+#pragma once
+#include "ref_counter.h"
+
+namespace pfc {
+	//! Base class for list nodes. Implemented by list implementers.
+	template<typename t_item> class _list_node : public refcounted_object_root {
+	public:
+		typedef _list_node<t_item> t_self;
+
+        template<typename ... arg_t> _list_node(arg_t && ... arg) : m_content( std::forward<arg_t>(arg) ...) {}
+
+		t_item m_content;
+
+		virtual t_self * prev() throw() {return NULL;}
+		virtual t_self * next() throw() {return NULL;}
+
+		t_self * walk(bool forward) throw() {return forward ? next() : prev();}
+	};
+
+	template<typename t_item> class const_iterator {
+	public:
+		typedef _list_node<t_item> t_node;
+		typedef refcounted_object_ptr_t<t_node> t_nodeptr;
+		typedef const_iterator<t_item> t_self;
+		
+		bool is_empty() const throw() {return m_content.is_empty();}
+		bool is_valid() const throw() {return m_content.is_valid();}
+		void invalidate() throw() {m_content = NULL;}
+
+		void walk(bool forward) throw() {m_content = m_content->walk(forward);}
+		void prev() throw() {m_content = m_content->prev();}
+		void next() throw() {m_content = m_content->next();}
+
+		//! For internal use / list implementations only! Do not call!
+		t_node* _node() const throw() {return m_content.get_ptr();}
+
+		const_iterator() {}
+		const_iterator(t_node* source) : m_content(source) {}
+		const_iterator(t_nodeptr const & source) : m_content(source) {}
+		const_iterator(t_self const & other) : m_content(other.m_content) {}
+		const_iterator(t_self && other) : m_content(std::move(other.m_content)) {}
+
+		t_self const & operator=(t_self const & other) {m_content = other.m_content; return *this;}
+		t_self const & operator=(t_self && other) {m_content = std::move(other.m_content); return *this;}
+
+		const t_item& operator*() const throw() {return m_content->m_content;}
+		const t_item* operator->() const throw() {return &m_content->m_content;}
+
+		const t_self & operator++() throw() {this->next(); return *this;}
+		const t_self & operator--() throw() {this->prev(); return *this;}
+		t_self operator++(int) throw() {t_self old = *this; this->next(); return old;}
+		t_self operator--(int) throw() {t_self old = *this; this->prev(); return old;}
+
+		bool operator==(const t_self & other) const throw() {return this->m_content == other.m_content;}
+		bool operator!=(const t_self & other) const throw() {return this->m_content != other.m_content;}
+
+		// Returns pointer to referenced item - null if iterator isn't valid
+		const t_item* get() const noexcept { return this->m_content.is_valid() ? &this->m_content->m_content : nullptr; }
+	protected:
+		t_nodeptr m_content;
+	};
+	template<typename t_item> class iterator : public const_iterator<t_item> {
+	public:
+		typedef const_iterator<t_item> t_selfConst;
+		typedef iterator<t_item> t_self;
+		typedef _list_node<t_item> t_node;
+		typedef refcounted_object_ptr_t<t_node> t_nodeptr;
+
+		iterator() {}
+		iterator(t_node* source) : t_selfConst(source) {}
+		iterator(t_nodeptr const & source) : t_selfConst(source) {}
+		iterator(t_self const & other) : t_selfConst(other) {}
+		iterator(t_self && other) : t_selfConst(std::move(other)) {}
+
+		t_self const & operator=(t_self const & other) {this->m_content = other.m_content; return *this;}
+		t_self const & operator=(t_self && other) {this->m_content = std::move(other.m_content); return *this;}
+
+		t_item& operator*() const throw() {return this->m_content->m_content;}
+		t_item* operator->() const throw() {return &this->m_content->m_content;}
+
+		const t_self & operator++() throw() {this->next(); return *this;}
+		const t_self & operator--() throw() {this->prev(); return *this;}
+		t_self operator++(int) throw() {t_self old = *this; this->next(); return old;}
+		t_self operator--(int) throw() {t_self old = *this; this->prev(); return old;}
+
+		bool operator==(const t_self & other) const throw() {return this->m_content == other.m_content;}
+		bool operator!=(const t_self & other) const throw() {return this->m_content != other.m_content;}
+
+		// Returns pointer to referenced item - null if iterator isn't valid
+		t_item* get() const noexcept { return this->m_content.is_valid() ? &this->m_content->m_content : nullptr; }
+	};
+
+	template<typename item_t> class forward_iterator {
+		iterator<item_t> m_iter;
+	public:
+		typedef forward_iterator<item_t> self_t;
+		void operator++() { ++m_iter; }
+
+		item_t& operator*() const throw() { return *m_iter; }
+		item_t* operator->() const throw() { return &*m_iter; }
+
+		bool operator==(const self_t& other) const { return m_iter == other.m_iter; }
+		bool operator!=(const self_t& other) const { return m_iter != other.m_iter; }
+
+		forward_iterator() {}
+		forward_iterator(iterator<item_t>&& i) : m_iter(std::move(i)) {}
+	};
+
+
+	template<typename item_t> class forward_const_iterator {
+		const_iterator<item_t> m_iter;
+	public:
+		typedef forward_const_iterator<item_t> self_t;
+		void operator++() { ++m_iter; }
+
+		const item_t& operator*() const throw() { return *m_iter; }
+		const item_t* operator->() const throw() { return &*m_iter; }
+
+		bool operator==(const self_t& other) const { return m_iter == other.m_iter; }
+		bool operator!=(const self_t& other) const { return m_iter != other.m_iter; }
+
+		forward_const_iterator() {}
+		forward_const_iterator(const_iterator<item_t>&& i) : m_iter(std::move(i)) {}
+	};
+
+	template<typename t_comparator = comparator_default>
+	class comparator_list {
+	public:
+		template<typename t_list1, typename t_list2>
+		static int compare(const t_list1 & p_list1, const t_list2 & p_list2) {
+			typename t_list1::const_iterator iter1 = p_list1.first();
+			typename t_list2::const_iterator iter2 = p_list2.first();
+			for(;;) {
+				if (iter1.is_empty() && iter2.is_empty()) return 0;
+				else if (iter1.is_empty()) return -1;
+				else if (iter2.is_empty()) return 1;
+				else {
+					int state = t_comparator::compare(*iter1,*iter2);
+					if (state != 0) return state;
+				}
+				++iter1; ++iter2;
+			}
+		}
+	};
+
+	template<typename t_list1, typename t_list2>
+	static bool listEquals(const t_list1 & p_list1, const t_list2 & p_list2) {
+		typename t_list1::const_iterator iter1 = p_list1.first();
+		typename t_list2::const_iterator iter2 = p_list2.first();
+		for(;;) {
+			if (iter1.is_empty() && iter2.is_empty()) return true;
+			else if (iter1.is_empty() || iter2.is_empty()) return false;
+			else if (*iter1 != *iter2) return false;
+			++iter1; ++iter2;
+		}
+	}
+
+	template<typename comparator_t = comparator_default>
+	class comparator_stdlist { 
+	public:
+		template<typename t_list1, typename t_list2>
+		static int compare(const t_list1 & p_list1, const t_list2 & p_list2) {
+			auto iter1 = p_list1.begin();
+			auto iter2 = p_list2.begin();
+			for(;;) {
+				const bool end1 = iter1 == p_list1.end();
+				const bool end2 = iter2 == p_list2.end();
+				if ( end1 && end2 ) return 0;
+				else if ( end1 ) return -1;
+				else if ( end2 ) return 1;
+				else {
+					int state = comparator_t::compare(*iter1,*iter2);
+					if (state != 0) return state;
+				}
+				++iter1; ++iter2;
+			}
+		}
+	};
+}
+
+namespace std {
+
+	template<typename item_t>
+	struct iterator_traits< pfc::forward_iterator< item_t > > {
+		typedef ptrdiff_t difference_type;
+		typedef item_t value_type;
+		typedef value_type* pointer;
+		typedef value_type& reference;
+		typedef std::forward_iterator_tag iterator_category;
+	};
+	template<typename item_t>
+	struct iterator_traits< pfc::forward_const_iterator< item_t > > {
+		typedef ptrdiff_t difference_type;
+		typedef item_t value_type;
+		typedef const value_type* pointer;
+		typedef const value_type& reference;
+		typedef std::forward_iterator_tag iterator_category;
+	};
+}
\ No newline at end of file